c++ - Openssl C++ AES解密添加意外符号
问题描述
我正在尝试在 C++ 中解密已使用 Linux 命令加密的文件:openssl enc -aes-256-cbc -nosalt -K "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" -iv "5DF6E0E2761359D30A82750 file.json2E0E2761359D30A82750 file. enc
解密效果很好,但是当我在终端中打印文件时,文件末尾会出现意外符号,如下图所示 Image
这是我的 C++ 代码,有人可以帮帮我吗?
int main(int argc, char **argv)
{
EVP_CIPHER_CTX *en, *de;
en = EVP_CIPHER_CTX_new();
de = EVP_CIPHER_CTX_new();
unsigned char key_data[] = {0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B,0x78, 0x52, 0xB8, 0x55};
int key_data_len = 32;
std::ifstream in("file.enc");
std::string contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
unsigned char iv[] = {0x5D, 0xF6, 0xE0, 0xE2, 0x76, 0x13, 0x59, 0xD3, 0x0A, 0x82, 0x75, 0x05, 0x8E, 0x29, 0x9F, 0xCC};
EVP_CIPHER_CTX_init(en);
EVP_EncryptInit_ex(en, EVP_aes_256_cbc(), NULL, key_data, iv);
EVP_CIPHER_CTX_init(de);
EVP_DecryptInit_ex(de, EVP_aes_256_cbc(), NULL, key_data, iv);
char *plaintext;
int len = strlen(contents.c_str())+1;
plaintext = (char *)aes_decrypt(de, (unsigned char *)contents.c_str(), &len);
printf("%s", plaintext);
free(plaintext);
EVP_CIPHER_CTX_cleanup(en);
EVP_CIPHER_CTX_cleanup(de);
}
以及解密的功能:
unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len)
{
int p_len = *len, f_len = 0;
unsigned char *plaintext = (unsigned char *)calloc(sizeof(char*), p_len);
EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len);
*len = p_len + f_len;
return plaintext;
}
已解决:我必须删除编码器 PKCS#7 填充添加的PKCS#7 填充
解决方案
输入长度不正确 -strlen(contents.c_str()) + 1
将返回长度,包括不应包含的额外空字节,因为它不是加密数据的一部分,或者返回加密数据中第一个空字节的数据长度(如果有)。你应该contents.size()
改用。这会导致EVP_DecryptUpdate
解密所有数据,包括带有填充的最后一个块,并期望更多数据并EVP_DecryptFinal_ex
在此之后失败。使用正确的长度,最后一个块的填充将按预期被剥离。
输出缓冲区长度也存在问题 - 它sizeof(char*) * p_len
不是sizeof(char) * (p_len + EVP_CIPHER_block_size(EVP_aes_256_cbc()))
. EVP_DecryptUpdate
要求输出缓冲区足够大以容纳输入长度 + 密码块大小。
您还应该确保仅使用缓冲区len
中的数据-将输出数据直到空字节,这可能不包含在解密数据中。plaintext
printf
推荐阅读
- javascript - 在每一步之前等待页面加载的递归表公式函数
- java - 无法在此处初始化数组
- php - 我将数据从索引转换为进程时出错“类 mysqli_result 的对象无法转换为 int”
- c# - WPF菜单不停留在顶部
- c# - 每次测试都会调用 OneTimesetup,我认为 OneTimesetup 就像 BeforeSuite,TestNG 注释
- c# - ConfigureAwait(false) 维护线程身份验证,但默认情况下不
- php - 如何使用 docker-compose 通过 nginx 路由我的 php 服务器?
- julia - 使用 `Int((n+1)/2)`、`round(Int, (n+1)/2)` 或 `Int((n+1)//2)` 哪个更好?
- java - 如果 Android Studio 的 for 循环忽略嵌套
- amazon-web-services - 限制 amazon-s3 仅访问 android 应用程序