c++caescryptoapiwincrypt

AES-128 encryption using WinCrypt


I need to encrypt strings under AES-128 for my C/C++ app making use of WinCrypt.

Just for understanding how the whole thing works, I have written a program to encrypt a 16 byte string with a 16 byte AES key (128 bits) but it is not working as expected (and the MSDN examples are not helping).

My main problem is with the call to CryptEncrypt, I may not have clear how to use the parameters:

Here is my code:

#include <windows.h> 
#include <stdio.h>
#include <wincrypt.h>
#define ENCRYPT_ALGORITHM CALG_AES_128

int main()
{

  HCRYPTPROV hCryptProv;
  HCRYPTKEY hKey;

//---------------------------------------------------------------
// Get the handle to the provider.
if(CryptAcquireContext(
    &hCryptProv, 
    NULL, 
    NULL, //MS_ENH_RSA_AES_PROV
    PROV_RSA_AES, 
    0))
{
    printf("A cryptographic provider has been acquired. \n");
}
else
{
    printf("Error during CryptAcquireContext!\n");
    exit(1);
}


//---------------------------------------------------------------
//  Create a random session key. 

 if(CryptGenKey(
          hCryptProv, 
          ENCRYPT_ALGORITHM, 
          CRYPT_EXPORTABLE, //KEYLENGTH | CRYPT_EXPORTABLE, 
          &hKey))
 {
         printf("A session key has been created.\n");
 } 
 else
 {
          printf("Error during CryptGenKey.\n"); 
          exit(1);
 }
}

char text_test [] = "abcdabcdabcdabcd";
   DWORD text_len = strlen(text_test);

   printf("PlainText: %s\n",text_test);
   printf("Buf Len: %d\n",text_len);

   if (!CryptEncrypt(hKey,
                    NULL,  // hHash = no hash
                    1,  // Final
                    0,     // dwFlags
                    &text_test, //*pbData
                    &text_len,  //*pdwDataLen
                    32)) {      //dwBufLen
     printf("Encryption failed\n");
   }

   printf("CipherText: %s\n",text_test);
   printf("Len: %d\n",text_len);

   if (!CryptDecrypt(hKey,
                    NULL,  // hHash = no hash
                    1,  // Final
                    0,     // dwFlags
                    &text_test,
                    &text_len)) {
     printf("Decryption failed\n");
   }

   printf("PlainText: %s\n",text_test);
   printf("Len: %d\n",text_len);
.
.
.
CryptDestroyKey(hKey)
.
.
CryptReleaseContext(hCryptProv, 0)
.

The output in the cmd is:

enter image description here

Can anyone explain me why the decrypted string is longer and which is the correct use of that three parameters of CryptEncrypt? I set the last value to 32 because after some trial and error that was the only value which made this stuff work. Help please and thank you in advance!


Solution

  • I am new to crytography too, but this code from here might have your solution:

      // This acts as both the length of bytes to be encoded (on input) and the
      // number of bytes used in the resulting encrypted data (on output).
      DWORD length = kAesBytes128;
      if (!CryptEncrypt(hKey,
                        NULL,  // hHash = no hash
                        true,  // Final
                        0,     // dwFlags
                        reinterpret_cast<BYTE*>(encrypted->data()),
                        &length,
                        encrypted->length())) {
        throw std::runtime_error("Encryption failed");
      }
    
      // See comment above.
      encrypted->chop(length - kAesBytes128);
    

    Or i might have some working from a similar project code using Crypto++