OpenSSL AES_cfb128_encrypt C++
Posted
技术标签:
【中文标题】OpenSSL AES_cfb128_encrypt C++【英文标题】: 【发布时间】:2014-06-19 10:15:02 【问题描述】:我尝试实现一个“非常”简单的加密/解密示例。我需要它用于我想加密一些用户信息的项目。我无法加密整个数据库,只能加密表中的某些字段。
数据库和项目的其余大部分工作,除了加密: 这是它的简化版本:
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <iostream>
#include <string.h>
using namespace std;
int main()
/* ckey and ivec are the two 128-bits keys necessary to
en- and recrypt your data. Note that ckey can be
192 or 256 bits as well
*/
unsigned char ckey[] = "helloworldkey";
unsigned char ivec[] = "goodbyworldkey";
int bytes_read;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
unsigned char decryptdata[AES_BLOCK_SIZE];
/* data structure that contains the key itself */
AES_KEY keyEn;
/* set the encryption key */
AES_set_encrypt_key(ckey, 128, &keyEn);
/* set where on the 128 bit encrypted block to begin encryption*/
int num = 0;
strcpy( (char*)indata , "Hello World" );
bytes_read = sizeof(indata);
AES_cfb128_encrypt(indata, outdata, bytes_read, &keyEn, ivec, &num, AES_ENCRYPT);
cout << "original data:\t" << indata << endl;
cout << "encrypted data:\t" << outdata << endl;
AES_cfb128_encrypt(outdata, decryptdata, bytes_read, &keyEn, ivec, &num, AES_DECRYPT);
cout << "input data was:\t" << decryptdata << endl;
return 0;
但是“解密”数据的输出是一些随机字符,但是每次执行代码后它们都是一样的。 outdata
每次执行都会改变...
我尝试调试并寻找解决方案,但找不到任何解决我的问题的方法。 现在我的问题是,这里出了什么问题?还是我完全误解了提供的功能?
【问题讨论】:
您是否也尝试过使用AES_set_decrypt_key
?对我来说似乎很奇怪,但是,嘿,这个功能必须有一个用途。
您确定要使用低级 AES 加密功能吗?使用高级 EVP 界面会更好。
另外,与您的问题有些无关,但不要将加密数据打印到标准输出。它不是 ASCII 数据。如果一定要打印出来,先用base64编码。
您还使用“helloworldkey”作为 128 位密钥,但该数组只有 14 个字符(包括 NUL 终止符)或 112 位。与 IV 相同。
你应该不使用AES_encrypt
和朋友。您应该使用EVP_*
函数。请参阅 OpenSSL wiki 上的 EVP Symmetric Encryption and Decryption。事实上,您可能应该使用经过身份验证的加密,因为它提供 机密性和真实性。请参阅 OpenSSL wiki 上的 EVP Authenticated Encryption and Decryption。
【参考方案1】:
问题在于AES_cfb128_encrypt
修改了ivec
(它必须这样才能允许链接)。您的解决方案是创建ivec
的副本并在每次调用AES_cfb128_encrypt
之前对其进行初始化,如下所示:
const char ivecstr[AES_BLOCK_SIZE] = "goodbyworldkey\0";
unsigned char ivec[AES_BLOCK_SIZE];
memcpy( ivec , ivecstr, AES_BLOCK_SIZE);
然后在第二次致电AES_cfb128_encrypt
之前重复memcpy
。
注意 1: 您的初始向量太短了一个字节,所以我在其末尾添加了一个明确的附加 \0
。复制或传递字符串时,应确保所有字符串的长度正确。
注意 2: 任何使用加密的代码都应该真正避免使用strcpy
或任何其他未经检查的长度副本。这是一个危险。
【讨论】:
非常感谢!做到了。我忽略了 ivec 被修改的事实。以上是关于OpenSSL AES_cfb128_encrypt C++的主要内容,如果未能解决你的问题,请参考以下文章
openssl pem转cer文件 并用base64编码解码过程