我在正确解密字符串时遇到了一些麻烦。令人愤怒的是,它只是前几个字节搞砸了,其余字符都是正确的。
因此,当我只是使用硬编码的 IV 进行加密和解密时,我的测试程序运行良好。该程序接受一个字符串,对其进行加密(使用 AES),然后我得到加密二进制文件的十六进制表示。当我试图将 IV 附加到密文的末尾时,问题就出现了。奇怪的是,十六进制字符串的长度在附加 IV 后并没有增加。但是,解密功能似乎是从密文末尾获取IV,否则它无法解密任何内容,对吧?
我尝试了很多不同的东西,比如创建一个精确大小的缓冲区,并使用memcpy
. 这是代码:
AES 加密
int encryptAes(const char *plainText, char *cipherText, const char *key) {
unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
int plainTextLength = strlen(plainText);
int cipherTextLength = 0;
int blockLength = 0;
static const int MAX_PADDING_LENGTH = 16;
EVP_CIPHER_CTX encryptCtx;
EVP_CIPHER_CTX_init(&encryptCtx);
EVP_EncryptInit_ex(&encryptCtx, EVP_aes_256_cbc(), NULL, key, iv);
if (!EVP_EncryptUpdate(&encryptCtx, cipherText, &blockLength, (unsigned char *) plainText, plainTextLength) ) {
printf("Error in EVP_EncryptUpdate \n");
return 1;
}
cipherTextLength += blockLength;
if (!EVP_EncryptFinal_ex(&encryptCtx, cipherText + cipherTextLength, &blockLength)) {
printf("Error in EVP_EncryptFinal_ex \n");
return 1;
}
cipherTextLength += blockLength;
// Append the IV
memcpy(cipherText + cipherTextLength, iv, 16);
EVP_CIPHER_CTX_cleanup(&encryptCtx);
return cipherTextLength;
}
AES 解密
int decryptAes(const char *cipherText, char *decipheredPlainText, const size_t cipherTextLength, const char *key) {
// unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
unsigned char iv[16];
memcpy(iv, cipherText + cipherTextLength, 16);
int plainTextLength = 0;
int blockLength = 0;
EVP_CIPHER_CTX decryptCtx;
EVP_CIPHER_CTX_init(&decryptCtx);
EVP_DecryptInit_ex(&decryptCtx, EVP_aes_256_cbc(), NULL, key, iv);
if (!EVP_DecryptUpdate(&decryptCtx, decipheredPlainText, &blockLength, cipherText, cipherTextLength)) {
printf("Error in EVP_DecryptUpdate\n");
return 1;
}
plainTextLength += blockLength;
if (!EVP_DecryptFinal_ex(&decryptCtx, decipheredPlainText + plainTextLength, &blockLength)) {
printf("Error in EVP_DecryptFinal_ex\n");
return 1;
}
plainTextLength += blockLength;
decipheredPlainText[plainTextLength] = '\0';
EVP_CIPHER_CTX_cleanup(&decryptCtx);
return plainTextLength;
}
这将产生输出:
Original Plain Text [cipher cipher cipher cipher CIPHER TEXT! 187? 1$5 78@2 14 .TӒ��틪�ձ1z.$�?�U���<y]
Hexadecimal is [be1c1aaa5827be124023a96a3360da922c244acd845e8914d03cfac69d312948e10f8ef7a99a64acbc6996724315f6cb0bf441ba3b08ab25cae64389f6ded77b1579e847d3e18ca89e71a3c4ec5ca4e3089b7bc2e6bc9ef8d175406bf4b53005a91e285d117e5990176d85793bd75853]
Decrypted Plain Text [�}kaw&d��~C�Rmfpher cipher CIPHER TEXT! 187? 1$5 78@2 14 .TӒ��틪�ձ1z.$�?�U���<y]
如果我memcpy(cipherText + cipherTextLength, iv, 16);
从加密函数中删除该行,并在解密函数的开头取消注释硬编码的 IV(并注释以下两行),则输出是正确的:
Original Plain Text [cipher cipher cipher cipher CIPHER TEXT! 187? 1$5 78@2 14 .TӒ��틪�ձ1z.$�?�U���<y]
Hexadecimal is [be1c1aaa5827be124023a96a3360da922c244acd845e8914d03cfac69d312948e10f8ef7a99a64acbc6996724315f6cb0bf441ba3b08ab25cae64389f6ded77b1579e847d3e18ca89e71a3c4ec5ca4e3089b7bc2e6bc9ef8d175406bf4b53005a91e285d117e5990176d85793bd75853]
Decrypted Plain Text [cipher cipher cipher cipher CIPHER TEXT! 187? 1$5 78@2 14 .TӒ��틪�ձ1z.$�?�U���<y]
笔记!, 十六进制在两种情况下都是相同的。
谁能看到我在这里出错的地方。我以前遇到过类似的事情,但似乎不记得我是如何解决的。显然,在尝试附加 IV 时有一些事情正在进行中。有足够的空间cipherText
来容纳 IV 的添加。
提前致谢。