You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OpenSSL AESNI汇编函数时aes_cbc_encrypt()解密异常求助

AES-NI CBC加解密结果错误的原因与修复

你的测试代码解密结果不正确,核心问题是CBC模式加密过程会修改传入的IV缓冲区,而你解密时误用了被修改后的IV。另外还有几个需要注意的细节:

核心问题:IV被加密函数修改

aesni_cbc_encrypt在加密模式下,每处理完一个数据块后,会自动将IV更新为当前的密文块(这是CBC模式的流程要求)。你在加密后直接使用同一个IV变量进行解密,此时IV已经不是原始值,导致解密逻辑错误。

修复步骤

  1. 备份原始IV:在加密前复制一份原始IV,解密时使用备份的IV。
  2. 确保密钥初始化正确:aesni_set_decrypt_key需要正确初始化解密用的轮密钥结构,你的代码中已调用该函数,只要函数实现正常即可。

修正后的测试代码:

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

int aesni_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
int aesni_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int enc);

int main()
{
    int i;
    unsigned char key[] = "\xE0\xE6\x0C\x86\xF1\x10\xF5\x3A\x4E\x65\x88\x79\x74\xB1\x4E\x3D\x06\x22\x9D\xB9\x4E\x26\x25\xBE\xD1\x18\x2B\x56\x73\xAB\x44\xF3";
    unsigned char iv[]  = "\x06\x22\x9D\xB9\x4E\x26\x25\xBE\xD1\x18\x2B\x56\x73\xAB\x44\xF3";
    unsigned char original_iv[16];
    memcpy(original_iv, iv, 16); // 备份原始IV
    unsigned char in[]  = "\x64\x6f\x20\x77\x68\x61\x74\x63\x68\x61\x20\x68\x61\x66\x74\x61";
    unsigned char out[16];
    unsigned char tmp[16];

    // 打印明文
    size_t blksz = 16;
    for (i=0;i<blksz;i++)
        printf("%02x ", in[i]);
    puts("");

    AES_KEY ks;
    aesni_set_encrypt_key(key, 256, &ks);
    aesni_cbc_encrypt(in, tmp, blksz, &ks, iv, 1); // 加密,此时iv已被修改

    // 打印密文
    for (i=0;i<blksz;i++)
        printf("%02x ", tmp[i]);
    puts("");

    // 解密:恢复原始IV
    memcpy(iv, original_iv, 16);
    aesni_set_decrypt_key(key, 256, &ks);
    aesni_cbc_encrypt(tmp, out, blksz, &ks, iv, 0); // 解密

    // 打印解密后的明文
    for (i=0;i<blksz;i++)
        printf("%02x ", out[i]);
    puts("");

    return 0;
}

额外注意事项

  • 直接调用OpenSSL的内部汇编函数(如aesni_*系列)没有官方API兼容性承诺,OpenSSL版本升级可能会改变这些函数的签名或内部逻辑,生产环境使用需谨慎。
  • 若处理多块数据,CBC模式要求明文长度必须是AES块大小(16字节)的倍数,不足时需要添加填充(如PKCS#7),你的测试数据刚好是16字节,所以无需处理。

内容的提问来源于stack exchange,提问作者shawnixer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:50:18