Need to Sync C# and C++ Cryptography

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
<pre>C++ Code:



bool MyEncryptFile(

LPTSTR pszSourceFile,

LPTSTR pszDestinationFile,

LPTSTR pszPassword)

{



//---------------------------------------------------------------

// Declare and initialize local variables.



bool fReturn = false;

HANDLE hSourceFile = INVALID_HANDLE_VALUE;

HANDLE hDestinationFile = INVALID_HANDLE_VALUE;

HCRYPTPROV hCryptProv = NULL;

HCRYPTKEY hKey = NULL;

HCRYPTKEY hDuplicateKey = NULL;

HCRYPTKEY hXchgKey = NULL;

HCRYPTHASH hHash = NULL;

PBYTE pbKeyBlob = NULL;

DWORD dwKeyBlobLen;

PBYTE pbBuffer = NULL;

DWORD dwBlockLen;

DWORD dwBufferLen;

DWORD dwCount;



BYTE *pbData1 = (BYTE*)"CRYPT_MODE_CBC";

BYTE *pbData2= (BYTE*)"1234567890123456";

BYTE *pbData3 = (BYTE*)"SALT@1";



//---------------------------------------------------------------

// Open the source file.



hSourceFile = CreateFile(

pszSourceFile,

FILE_READ_DATA,

FILE_SHARE_READ,

NULL,

OPEN_ALWAYS,

FILE_ATTRIBUTE_NORMAL,

NULL);



if(INVALID_HANDLE_VALUE != hSourceFile)

{

_tprintf(

TEXT("The source plaintext file, %s, is open. n"),

pszSourceFile);

}

else

{

MyHandleError(

TEXT("Error opening source plaintext file!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//---------------------------------------------------------------

// Open the destination file.



hDestinationFile = CreateFile(

pszDestinationFile,

FILE_WRITE_DATA,

FILE_SHARE_READ,

NULL,

OPEN_ALWAYS,

FILE_ATTRIBUTE_NORMAL,

NULL);



if(INVALID_HANDLE_VALUE != hDestinationFile)

{

_tprintf(

TEXT("The destination file, %s, is open. n"),

pszDestinationFile);

}

else

{

MyHandleError(

TEXT("Error opening destination file!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//---------------------------------------------------------------

// Get the handle to the default provider.

//-------------------------------------------------------------------

// provider context



LPCWSTR UserName = L"test"; // name of the key container



// to be used



if(CryptAcquireContext(

&hCryptProv, // handle to the CSP

UserName, // container name

NULL, // use the default provider

PROV_RSA_AES, // provider type

0)) // flag values

{

_tprintf(

TEXT("A cryptographic provider has been acquired. n"));

}

else

{

MyHandleError(

TEXT("Error during CryptAcquireContext!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



if(CryptGenKey(

hCryptProv,

ENCRYPT_ALGORITHM,

KEYLENGTH | CRYPT_EXPORTABLE,

&hKey))

{

_tprintf(TEXT("A session key has been created. n"));

}

else

{

MyHandleError(

TEXT("Error during CryptGenKey. n"),

GetLastError());

goto Exit_MyEncryptFile;

}



// Duplicate the key.



if (CryptDuplicateKey(

hKey,

NULL,

0,

&hDuplicateKey))

{

_tprintf(TEXT("A session key has been duplicated. n"));

}

else

{

MyHandleError(

TEXT("Error in duplicating session key. n"),

GetLastError());

goto Exit_MyEncryptFile;

}



DWORD dwMode;

dwMode = CRYPT_MODE_CBC;

if(CryptSetKeyParam(

hKey,

KP_MODE,

(BYTE*)&dwMode,

0

))

{

// Print the cipher mode.

_tprintf(TEXT("Default cipher mode: %dn"), pbData1);

}

else

{

MyHandleError(TEXT("Error during CryptSetKeyParam cipher block mode."),

GetLastError());

goto Exit_MyEncryptFile;

}



if(CryptSetKeyParam(

hKey,

KP_IV,

pbData2,

0

))

{

// Print the cipher mode.

_tprintf(TEXT("Default cipher mode: %dn"), pbData2);

}

else

{

MyHandleError(TEXT("Error during CryptGetKeyParam cipher mode."),

GetLastError());

goto Exit_MyEncryptFile;

}



// Read the SALT.

// Get the length of the salt.

if(!CryptGetKeyParam(

hKey,

KP_SALT,

NULL,

&dwCount,

0))

{

MyHandleError(TEXT("Error getting the salt length"),

GetLastError());

goto Exit_MyEncryptFile;

}



dwCount = strlen((char *)pbData3)+1;



// Get the salt.

if(CryptGetKeyParam(

hKey,

KP_SALT,

pbData3,

&dwCount,

0))

{

// Print the salt

_tprintf(TEXT("Default IV:"));

for(int i = 0; i < sizeof(dwCount); i++)

{

_tprintf(TEXT("%2.2x "),pbData3);

}



_tprintf(TEXT("n"));

}

else

{

MyHandleError(TEXT("Error getting the salt."),

GetLastError());

goto Exit_MyEncryptFile;

}



//-----------------------------------------------------------

// Get the handle to the exchange public key.



if(CryptGetUserKey(

hCryptProv,

AT_KEYEXCHANGE,

&hXchgKey))

{

_tprintf(

TEXT("The user public key has been retrieved. n"));

}

else

{

if(NTE_NO_KEY == GetLastError())

{

// No exchange key exists. Try to create one.

if(!CryptGenKey(

hCryptProv,

AT_KEYEXCHANGE,

CRYPT_EXPORTABLE,

&hXchgKey))

{

MyHandleError(

TEXT("Could not create a user public key.n"),

GetLastError());

goto Exit_MyEncryptFile;

}

}

else

{

MyHandleError(

TEXT("User public key is not available and may ")

TEXT("not exist.n"),

GetLastError());

goto Exit_MyEncryptFile;

}

}



//-----------------------------------------------------------

// Determine size of the key BLOB, and allocate memory.



if(CryptExportKey(

hKey,

hXchgKey,

SIMPLEBLOB,

0,

NULL,

&dwKeyBlobLen))

{

_tprintf(

TEXT("The key BLOB is %d bytes long. n"),

dwKeyBlobLen);

}

else

{

MyHandleError(

TEXT("Error computing BLOB length! n"),

GetLastError());

goto Exit_MyEncryptFile;

}



if(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen))

{

_tprintf(

TEXT("Memory is allocated for the key BLOB. n"));

}

else

{

MyHandleError(TEXT("Out of memory. n"), E_OUTOFMEMORY);

goto Exit_MyEncryptFile;

}



//-----------------------------------------------------------

// Encrypt and export the session key into a simple key

// BLOB.



if(CryptExportKey(

hKey,

hXchgKey,

SIMPLEBLOB,

0,

pbKeyBlob,

&dwKeyBlobLen))

{

_tprintf(TEXT("The key has been exported. n"));

}

else

{

MyHandleError(

TEXT("Error during CryptExportKey!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//-----------------------------------------------------------

// Release the key exchange key handle.

if(hXchgKey)

{

if(!(CryptDestroyKey(hXchgKey)))

{

MyHandleError(

TEXT("Error during CryptDestroyKey.n"),

GetLastError());

goto Exit_MyEncryptFile;

}



hXchgKey = 0;

}



//-----------------------------------------------------------

// Write the size of the key BLOB to the destination file.

if(!WriteFile(

hDestinationFile,

&dwKeyBlobLen,

sizeof(DWORD),

&dwCount,

NULL))

{

MyHandleError(

TEXT("Error writing header.n"),

GetLastError());

goto Exit_MyEncryptFile;

}

else

{

_tprintf(TEXT("A file header has been written. n"));

}



//-----------------------------------------------------------



// Write the key BLOB to the destination file.



if(!WriteFile(

hDestinationFile,

pbKeyBlob,

dwKeyBlobLen,

&dwCount,

NULL))

{

MyHandleError(

TEXT("Error writing header.n"),

GetLastError());

goto Exit_MyEncryptFile;

}

else

{

_tprintf(

TEXT("The key BLOB has been written to the ")

TEXT("file. n"));

}



// Free memory.



free(pbKeyBlob);



//-----------------------------------------------------------

// The file will be encrypted with a session key derived

// from a password.

// The session key will be recreated when the file is

// decrypted only if the password used to create the key is

// available.

//-----------------------------------------------------------

// Create a hash object.



if(CryptCreateHash(

hCryptProv,

CALG_SHA1,

0,

0,

&hHash))

{

_tprintf(TEXT("A hash object has been created. n"));



}

else

{

MyHandleError(

TEXT("Error during CryptCreateHash!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//-----------------------------------------------------------

// Hash the password.



if(CryptHashData(

hHash,

(BYTE *)pszPassword,

lstrlen(pszPassword),

0))

{

_tprintf(

TEXT("The password has been added to the hash. n"));

}

else

{

MyHandleError(

TEXT("Error during CryptHashData. n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//-----------------------------------------------------------

// Derive a session key from the hash object.

if(CryptDeriveKey(

hCryptProv,

ENCRYPT_ALGORITHM,

hHash,

KEYLENGTH,

&hKey))

{

_tprintf(

TEXT("An encryption key is derived from the ")

TEXT("password hash. n"));

}

else

{

MyHandleError(

TEXT("Error during CryptDeriveKey!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//---------------------------------------------------------------

// The session key is now ready. If it is not a key derived from

// a password, the session key encrypted with the private key

// has been written to the destination file.

//---------------------------------------------------------------

// Determine the number of bytes to encrypt at a time.

// This must be a multiple of ENCRYPT_BLOCK_SIZE.

// ENCRYPT_BLOCK_SIZE is set by a #define statement.



dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;



//---------------------------------------------------------------

// Determine the block size. If a block cipher is used,

// it must have room for an extra block.



if(ENCRYPT_BLOCK_SIZE > 1)

{

dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;

}

else

{

dwBufferLen = dwBlockLen;

}





//---------------------------------------------------------------

// Allocate memory.

if(pbBuffer = (BYTE *)malloc(dwBufferLen))

{

_tprintf(

TEXT("Memory has been allocated for the buffer. n"));

}

else

{

MyHandleError(TEXT("Out of memory. n"), E_OUTOFMEMORY);

goto Exit_MyEncryptFile;

}



//---------------------------------------------------------------

// In a do loop, encrypt the source file,

// and write to the source file.

bool fEOF = FALSE;

do

{

//-----------------------------------------------------------

// Read up to dwBlockLen bytes from the source file.



if(!ReadFile(

hSourceFile,

pbBuffer,

dwBlockLen,

&dwCount,

NULL))

{

MyHandleError(

TEXT("Error reading plaintext!n"),

GetLastError());

goto Exit_MyEncryptFile;

}



if(dwCount < dwBlockLen)

{

fEOF = TRUE;

}



//-----------------------------------------------------------

// Encrypt data.



if(!CryptEncrypt(

hKey,

NULL,

fEOF,

0,

pbBuffer,

&dwCount,

dwBufferLen

))

{

MyHandleError(

TEXT("Error during CryptEncrypt. n"),

GetLastError());

goto Exit_MyEncryptFile;

}



//-----------------------------------------------------------

// Write the encrypted data to the destination file.



if(!WriteFile(

hDestinationFile,

pbBuffer,

dwCount,

&dwCount,

NULL))

{

MyHandleError(

TEXT("Error writing ciphertext.n"),

GetLastError());

goto Exit_MyEncryptFile;



}



//-----------------------------------------------------------

// End the do loop when the last block of the source file

// has been read, encrypted, and written to the destination

// file.



} while(!fEOF);



fReturn = true;



Exit_MyEncryptFile:



//---------------------------------------------------------------



// Close files.



if(hSourceFile)

{

CloseHandle(hSourceFile);

}



if(hDestinationFile)

{

CloseHandle(hDestinationFile);

}



//---------------------------------------------------------------



// Free memory.



if(pbBuffer)

{

free(pbBuffer);

}





//-----------------------------------------------------------

// Release the hash object.



if(hHash)

{

if(!(CryptDestroyHash(hHash)))

{

MyHandleError(

TEXT("Error during CryptDestroyHash.n"),

GetLastError());

}

hHash = NULL;



}



//---------------------------------------------------------------

// Release the session key.



if(hKey)

{

if(!(CryptDestroyKey(hKey)))

{

MyHandleError(

TEXT("Error during CryptDestroyKey!n"),

GetLastError());

}

}



if (hDuplicateKey)

{

if (!CryptDestroyKey(hDuplicateKey))

{

MyHandleError(

TEXT("Error during CryptDestroyKey!n"),

GetLastError());

}

}





//---------------------------------------------------------------

// Release the provider handle.



if(hCryptProv)

{

if(!(CryptReleaseContext(hCryptProv, 0)))

{

MyHandleError(

TEXT("Error during CryptReleaseContext!n"),

GetLastError());

}

}



return fReturn;



} // End Encryptfile.





C# Code:



public static string Encrypt(string PlainText)

{

try

{

if (string.IsNullOrEmpty(PlainText))

return "";

byte[] initialVectorBytes = Encoding.ASCII.GetBytes(VECTOR);

byte[] saltValueBytes = Encoding.ASCII.GetBytes(SALT);

byte[] plainTextBytes = Encoding.UTF8.GetBytes(PlainText);

PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(KEY, saltValueBytes, HASH_ALGORITHM, PASSWORD_ITERATION);

byte[] keyBytes = DerivedPassword.GetBytes(KEYSIZE / 8);

RijndaelManaged symmetricKey = new RijndaelManaged();

symmetricKey.Mode = CipherMode.CBC;

byte[] cipherTextBytes = null;

using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes))

{

using (MemoryStream memStream = new MemoryStream())

{

using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))

{

cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

cryptoStream.FlushFinalBlock();

cipherTextBytes = memStream.ToArray();

memStream.Close();

cryptoStream.Close();

}

}

}

symmetricKey.Clear();

return Convert.ToBase64String(cipherTextBytes);

}

catch { throw; }

}



[/code]
INPUT PARMATERS (USERKEY, SALT, INITIALIZATION VECTOR, ITERATION PASSWORD, KEYSIZE, HASH)Please help in passing all the parameters to the c++ program. It will remove lot of hazzles in our project.http://stackoverflow.com/questions/2155678/decrypt-file-in-c-with-microsoft-crypt-api-that-was-encrypted-with-tripledes-in
Thanks & Regards
Guruprasath

View the full article
 
Back
Top