我正在尝试使用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_len
或string_size
应该是128作为AES块大小吗?
答案 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;