-1

我需要为使用 WinCrypt 的 C/C++ 应用程序在 AES-128 下加密字符串。

只是为了了解整个事情是如何工作的,我编写了一个程序来使用 16 字节 AES 密钥(128 位)加密 16 字节字符串,但它没有按预期工作(并且 MSDN 示例没有帮助)。

我的主要问题是调用 CryptEncrypt,我可能不清楚如何使用参数:

  • *pb数据
  • *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,因为经过反复试验,这是使这些东西起作用的唯一值。请帮助,并在此先感谢您!

4

2 回答 2

1

我也是密码学的新手,但这里的代码可能有你的解决方案:

  // 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++ 的类似项目代码的工作

于 2017-04-27T13:05:08.263 回答
0

是填充物。默认情况下,您将插入与您加密的字节相同数量的填充。忽略最后 16 个字节。前 16 个字节是您想要的。

于 2017-09-05T15:55:03.790 回答