【问题标题】:Using AES CBC from OpenSSL使用来自 OpenSSL 的 AES CBC
【发布时间】:2014-03-30 11:24:17
【问题描述】:

我正在编写 C++ 服务器函数,通过使用 AES CBC 128 位传递一个加密字符串,该函数将被称为 java 进程。我无法更改此 C++ 函数的签名。

为此,我在 C++ 代码中使用 openssl AES_set_decrypt_key() 和 AES_cbc_encrypt() 方法。 但是在 AES_cbc_encrypt() 的签名中有一个长度参数,我相信它是实际字符串的长度(未加密)。但是,我的 C++ 代码不知道实际长度。我是否采取了错误的方法?有人可以帮忙吗?

示例代码如下:

unsigned char* decrypt(unsigned char* l_cInput_ptr)
{
unsigned char key[] = "asdfghjklpoiuytr";
unsigned char iv[] = "asdfghjklpoiuytr";

unsigned char * dec_out = (unsigned char *)malloc(80*sizeof(char));
memset(dec_out, 0, 80);

AES_KEY dec_key;

AES_set_decrypt_key(key,128,&dec_key);
AES_cbc_encrypt(l_cInput_ptr, dec_out, 16, &dec_key, iv, AES_DECRYPT);

....
}

l_cInput_ptr 是加密字符串。 decrypt() 方法不知道实际字符串的长度。在这种情况下,我刚刚使用了 16 的虚拟值。而且我不能更改java代码。

【问题讨论】:

标签: openssl


【解决方案1】:

AES_cbc_encrypt()length参数是输入的长度。因此,对于解密,这是 加密 数据的长度,对于 CBC 模式下的 AES,它始终是 16 个字节的倍数(顺便说一下,从您的代码中不清楚您是如何做到的)重新获取由unsigned char* 指向的提供数据的长度。

解密后的数据将具有相同的长度并将被填充(通常是 PKCS# 7 填充,有时只是添加 NULL,但实际上可能是任何东西)。您必须在解密后删除此填充以获得原始明文。

【讨论】:

    【解决方案2】:

    是的,Andrey 是对的,我遇到了同样的问题。如果原始未加密文本长度不是 16 字节的倍数,则解密数据与未填充的原始数据长度相同。如果原始未加密文本长度是 16 字节 (n) 的倍数,则解密长度为 n + 1,填充 16 字节,我们需要将其删除。这是代码:

    AES_cbc_encrypt(&encrypted, &decrypted, length, &key2, iv2, 0);
    
    length = strlen(decrypted);
    if (length > AES_BLOCK_SIZE && (length % AES_BLOCK_SIZE == 0))
    {
        length = length - AES_BLOCK_SIZE;
        memset(decrypted + length, 0, AES_BLOCK_SIZE);
    }
    printf("xxx %s", decrypted);
    

    【讨论】:

      猜你喜欢
      • 2013-08-11
      • 2022-08-17
      • 2017-08-28
      • 2017-09-18
      • 2018-11-11
      • 2019-08-17
      • 2020-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多