不要正确加密Wincrypt

时间:2018-08-18 14:56:23

标签: c encryption aes wincrypt

我正在尝试使用wincrypt.h中的AES128将字符串加密为8个字节(64位)的大小,请注意,该字符串小于AES的块大小,即128位。 / strong>

HCRYPTKEY hKey;
if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
    dwStatus = GetLastError();
    printf("CryptDeriveKey failed: %x\n", dwStatus);
    CryptReleaseContext(hProv, 0);
    system("pause");
    return dwStatus;
}

printf("[+] CryptDeriveKey Success\n");

const size_t string_size = 8;
BYTE string[8] = { "Foooooo" };   // \0 counts as 1 byte
DWORD out_len = 8;


if (!CryptEncrypt(hKey, NULL, TRUE, 0, string, &out_len, string_size)) {
        printf("[-] CryptEncrypt failed\n");
}

printf("%s", string);
printf("\n");

if (!CryptDecrypt(hKey, NULL, TRUE, 0, string, &out_len)) {
    printf("[-] CryptDecrypt failed\n");

}

printf("%s", string);
printf("\n");

但是由于我得到以下输出,它看起来不能很好地进行加密/解密:

[+] CryptDeriveKey Success
Fooooooo
[-] CryptEncrypt failed
ÉÆ╠1╔P█ídhù;$§┴
[-] CryptDecrypt failed

我做错了什么? &out_lenstring_size应该是128作为AES块大小吗?

1 个答案:

答案 0 :(得分:1)

The docs for CryptEncrypt表示输入/输出长度以字节为单位,因此对于AES *,这应该是16的倍数

我认为这也是解决您问题的关键:CryptEncrypt是就地操作的-也就是说,它会使用输出密文覆盖输入纯文本。您的缓冲区太小,无法接收16字节的输出,因此在加密和解密操作之间,最后8个字节很可能已损坏。

尝试碰碰

function foo(){ var v = 123; }

Object.getOwnPropertyNames()

另外,请阅读PKCS7填充,这可能是Wincrypt确定您的密文错误的方式。

*,除了密文窃取模式或流模式。这些模式在解密时不会“失败”,因此wincrypt不会使用其中一种。


与您的问题无关,但是通过BYTE string[8] = { "Foooooo" }; const size_t string_size = 8;打印密文也不是一个好主意。通过以十六进制打印密文,您将获得更好的理解:

BYTE string[16] = { "Foooooo" }; const size_t string_size = 16;