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 替换 Mcrypt

openssl pem转cer文件 并用base64编码解码过程

Java AES 128 加密方式与 openssl 不同

php openssl aes-256-cbc key长度自动匹配了128的长度,为啥

测试openssl_encrypt

不支持 OpenSSL 密码 PSK-AES128-CCM8?