c++ - 使用 OpenSSL 的 AES 256-cbc 加密 C++

标签 c++ encryption cryptography

我正在尝试创建一个函数,我可以将一个字符串 key (我有另一种算法来生成 key )放入一个消息字符串中。该函数应使用 OpenSSL 库中的 aes256-cbc 加密和解密文本

#define AES_KEYLENGTH 256
string cipher_AES(string key, string message);

int main(int argc, char* argv[])
{
     cipher_AES("115792089237316195423570985008687907853269984665640564039457583884239776304164", "Hello, how are you, you mad?");
     return 0;
}

// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
    const unsigned char * p = (const unsigned char*)pv;
    if (NULL == pv)
        printf("NULL");
    else
    {
        size_t i = 0;
        for (; i<len;++i)
            printf("%02X ", *p++);
    }
    printf("\n");
}

/* computes the ciphertext from plaintext and key using AES256-CBC algorithm */
string cipher_AES(string key, string message)
{
    size_t inputslength = message.length();
    unsigned char aes_input[inputslength];
    unsigned char aes_key[AES_KEYLENGTH];
    memset(aes_input, 0, inputslength/8);
    memset(aes_key, 0, AES_KEYLENGTH/8);
    strcpy((char*) aes_input, message.c_str());
    strcpy((char*) aes_key, key.c_str());

    /* init vector */
    unsigned char iv[AES_BLOCK_SIZE];
    memset(iv, 0x00, AES_BLOCK_SIZE);

    // buffers for encryption and decryption
    const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
    unsigned char enc_out[encslength];
    unsigned char dec_out[inputslength];
    memset(enc_out, 0, sizeof(enc_out));
    memset(dec_out, 0, sizeof(dec_out));

    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, AES_KEYLENGTH, &enc_key);
    AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv, AES_ENCRYPT);

    AES_set_decrypt_key(aes_key, AES_KEYLENGTH, &dec_key);
    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv, AES_DECRYPT);

    printf("original:\t");
    hex_print(aes_input, sizeof(aes_input));
    printf("encrypt:\t");
    hex_print(enc_out, sizeof(enc_out));

    printf("decrypt:\t");
    hex_print(dec_out, sizeof(dec_out));

    stringstream ss;
    for(int i = 0; i < encslength; i++)
    {
        ss << enc_out[i];
    }
    return ss.str(););
}

在输出中似乎有些东西是相同的,但不是全部:

original:       48 65 6C 6C 6F 2C 20 68 6F 77 20 61 72 65 20 79 6F 75 2C 20 79 6F 75 20 69 64 69 6F 74 3F
encrypt:        25 C3 B4 4B 92 68 2E DA 61 B6 AB 19 97 D3 90 8A 5F 8B 3C 4B 78 13 FC E1 3A AF 2C B5 3F C8 2B D7
decrypt:        17 EE 50 27 17 3F DC 89 55 D8 0C D4 4D AD 0B AE 6F 75 2C 20 79 6F 75 20 69 64 69 6F 74 3F

最佳答案

查看您的数据,第一个 block (16 个字节)是错误的,但后面的 block 是正确的。这表明解密时使用了错误的 IV。一些小测试(在第一次调用 AES_cbc_encrypt 之前和之后打印 IV)表明 IV 在这次调用期间确实发生了变化。

稍微浏览一下 OpenSSL 源代码表明它 changes the IV parameter to be the last block of the ciphertext加密时。

虽然在解密修复之前重置 IV,但您会重新生成正确的明文:

memset(iv, 0x00, AES_BLOCK_SIZE);
AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv, AES_DECRYPT);

关于c++ - 使用 OpenSSL 的 AES 256-cbc 加密 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43192493/

相关文章:

c++ - 从类的成员函数返回指针

javascript - CryptoJS AES 模式总是以 = 结尾

java - 将编码对象写入文件

ios - 是否可以在 iOS 上将 AES128 与 GCM 模式一起使用?

.net - PasswordDeriveBytes 与 Rfc2898DeriveBytes,已过时但速度更快

c++ - std::mutex 和 std::atomic 的链接问题

c++ - 为什么 istream 类的 operator<< 在 C++ 中有返回/参数类型的引用?

c++ - 奇怪的构造函数行为

java - 无法在 Android 上使用 AES 密码

将方程转换为 cnf,以便使用 sat 求解器