【问题标题】:OpenSSL AES_ecb_encrypt padding option?OpenSSL AES_ecb_encrypt 填充选项?
【发布时间】:2022-01-20 11:45:16
【问题描述】:

我在 Visual Studio 中构建了一个 C 项目,它仅使用 OpenSSL 使用 AES128 ECB 密码加密输入数据。

如果我的输入是 16 字节,那么输出是正确的,只要我得到错误的输出更短。

#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/aes.h>

int main(void)
{
    unsigned char aesKey[] = 
    {
        0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 
        0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
    };

    const unsigned char aesData[] = {0x35, 0x31, 0x30, 0x30}; // results in wrong output

    const unsigned char aesDataa[] = // results in correct output
    {
        0x35, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 
        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 
    }; 

    unsigned char out[32];

    AES_KEY aes_key;
    AES_set_encrypt_key((const unsigned char *)aesKey, 128, &aes_key);
    AES_ecb_encrypt(aesDataa, out, &aes_key, AES_ENCRYPT);

    for (int i = 0; i < 33; i++)
        printf("%x", out[i]);

    return 1;
}

我的例子:

输入十六进制:0x35313030

密钥十六进制:0x2B7E151628AED2A6ABF7158809CF4F3C

输出十六进制:0x2ba87a539758d476bb666bb525d14dbc

this 站点已针对其他站点进行了测试,并在 aes 硬件加速微控制器中实现了:

输出十六进制:0xb13278c7f7413d515c549f4042a5de8c

如果我输入这个:5100510051005100 那么他们都同意。

我必须介绍我自己的 PKCS#7 填充吗?如果是这样,有人可以指出我的实现吗?

我试图避免使用 EVP,因为我只会使用这种特定的加密方法和密码。

谢谢

【问题讨论】:

  • edit您的问题并添加更多详细信息。你如何检查输出是正确还是错误?显示正确和错误情况的输入和输出。显示minimal reproducible example
  • 已编辑。我只是认为这并不重要,因为我认为填充确实是问题所在。
  • 请创建一个minimal reproducible example,即我们可以编译和运行以重现问题的程序。还展示了如何为好的案例调用函数。我不知道填充是否是问题。重现问题可能有助于排除其他可能的错误。

标签: c openssl aes


【解决方案1】:

AES 128 算法需要 16 个字节作为输入。您的 aesData 数组只有 4 个字节长,因此这会导致 AES_ecb_encrypt 读取到触发 undefined behavior 的数组末尾。

将数组设为 16 字节宽:

const unsigned char aesData[16] = { 0x35, 0x31, 0x30, 0x30 }; 

这会将剩余元素隐式初始化为 0,因此现在结果与链接网站的结果相匹配。

另外,这里有一个错误:

for (int i = 0;i < 33;i++)
    printf("%x", out[i]);

读取到数组末尾之后。你想要:

for (int i = 0;i < 32;i++)
    printf("%x", out[i]);

此外,只有 16 个字节的输出数组被写入,因此您正在读取未初始化的字节。所以将out初始化为全零:

unsigned char out[32] = {0};

【讨论】:

  • 是的,效果很好。那么如果我的输入大于 16 字节呢?
  • @MichaelPapageorge 然后你需要对每个 16 字节的块进行多次加密。如果您使用 EVP 库,您可以一次加密更大的块。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 2020-02-19
  • 2019-11-24
相关资源
最近更新 更多