In previous posts, I wrote example code for generating MD5 Hash & SHA1 Hash using Windows Cryptography Functions. Here I am going to write about DES encryption/decryption algorithm with SHA1 based Hash key generated using Password.  This is most common way of generating password where in unique data is used to generate a Hash Key which is then used for encryption of the source data.


Below is the code example for the same,

//
//  Encrypt Data using DES algorithm with SHA1 based hash key derived from password 
//
BOOL EncryptDataUsingSHA1_DES(char *strPassword, BYTE *byteData, DWORD dwDataLen, DWORD dwBufferSize) 
{

 BOOL bResult = FALSE;
 HCRYPTPROV hProv = 0;
 HCRYPTHASH hHash = 0;
 HCRYPTKEY hCryptKey = 0;

 // Get handle to the crypto provider
 if (CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)  == FALSE )
 {
	 printf("\nCryptAcquireContext failed,  Error=0x%.8x", GetLastError());
	 goto Encrypt_End;
 }

 //Create SHA1 Hash 
 if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash) == FALSE)
 {
	 printf("\n CryptCreateHash failed,  Error=0x%.8x", GetLastError());
	 goto Encrypt_End;
 }

 //Generate SHA1 Hash using password 
 if( CryptHashData(hHash, (const BYTE*) strPassword, strlen(strPassword), 0) == FALSE)
 {
	 printf("\n CryptHashData failed,  Error=0x%.8x", GetLastError());
	 goto Encrypt_End;
 }

 //Now derive key using SHA1 hash for DES encryption     
 if( CryptDeriveKey(hProv, CALG_DES, hHash, CRYPT_EXPORTABLE, &hCryptKey) == FALSE )
 {
	 printf("\n CryptDeriveKey failed,  Error=0x%.8x", GetLastError());
	 goto Encrypt_End;
 }

 printf("\n********** Performing Encryption of data of length = %d", dwDataLen);

 //Finally encrypt the source data using DES encryption

 if( CryptEncrypt(hCryptKey, NULL, TRUE, 0, byteData,  &dwDataLen, dwBufferSize) == FALSE )
 {
	 printf("\n CryptEncrypt failed,  Error=0x%.8x", __FUNCTION__, GetLastError());
	 goto Encrypt_End;
 }

 printf("\n********** Encryption Successful,  Final encrypted data size %d", dwDataLen);

 bResult = TRUE;

Encrypt_End:

 if( hCryptKey )
	 CryptDestroyKey(hCryptKey);

 if( hHash )
	 CryptDestroyHash(hHash);

 if( hProv )
	 CryptReleaseContext(hProv, 0);

 return bResult; 

}


Above example uses following 3 steps to perform the encryption

  1. Generate the SHA1 Hash using the input password
  2. Derive the Key using SHA1 Hash for encryption
  3. Finally Encrypt the source data using the above key



The decryption code is almost identical except that we need to replace CryptEncrypt code section with CryptDecrypt function as shown below

 //Finally encrypt the source data using DES encryption
 if( CryptDecrypt(hCryptKey, NULL, TRUE, 0, byteData,  &dwDataLen) == FALSE )
 {
	 printf("\n CryptDecrypt failed,  Error=0x%.8x", __FUNCTION__, GetLastError());
	 goto Encrypt_End;
 }



Place the above function anywhere in your project and  invoke it using following code snippet

 char strPassword[]="securityxploded";
 char strSourceData[1024]="secret string";
 DWORD dwDataLen = strlen(strSourceData);

 EncryptDataUsingSHA1_DES(strPassword, (BYTE*) strSourceData, dwDataLen, 1024);



Here we use DES algorithm for encryption/decryption. We can also use other popular algorithms such as RC4 (CALG_RC4) and with different Hash generation algorithms such as SHA256, MD5 etc in place of SHA1.


See Also

CryptoCode: Index of All Crypto Articles