Шифрование AES-128 с использованием WinCrypt

Мне нужно зашифровать строки в AES-128 для моего приложения C/C++, использующего WinCrypt.

Просто для понимания того, как все это работает, я написал программу для шифрования 16-байтовой строки с помощью 16-байтового ключа AES (128 бит), но она не работает должным образом (и примеры MSDN не помогают).

Моя главная проблема с вызовом CryptEncrypt, у меня может не быть ясного, как использовать параметры:

  • * pbData
  • * pdwDataLen
  • dwBufLen

Вот мой код:

#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)
.

Выходные данные в cmd:

введите описание изображения здесь

Может кто-нибудь объяснить мне, почему расшифрованная строка длиннее и как правильно использовать эти три параметра CryptEncrypt? Я установил последнее значение равным 32, потому что после некоторых проб и ошибок это было единственное значение, которое заставило этот материал работать. Помогите пожалуйста и заранее спасибо!

2 ответа

Решение

Я тоже новичок в криптографии, но этот код здесь может иметь ваше решение:

  // 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);

Или я мог бы работать с похожим кодом проекта, используя Crypto++

Это набивка. По умолчанию вы добавляете равное количество отступов в качестве байтов, которые вы шифруете. Игнорировать последние 16 байтов. Первые 16 байтов - это то, что вы хотите.

Другие вопросы по тегам