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

OpenSSL中AES算法实现与标准加密流程不对应问题咨询

OpenSSL AES实现与标准流程差异疑问

我目前正在学习AES算法,发现OpenSSL中的AES实现似乎缺失了部分标准流程步骤。学习过程中参考了AES加密算法的公开动画演示资料与标准流程截图。

经梳理,OpenSSL的AES实现核心包含两个函数:

int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                                AES_KEY *key);

void AES_encrypt(const unsigned char *in, unsigned char *out,
                 const AES_KEY *key);
  • 第一个函数用于生成每一轮加密所需使用的轮密钥
  • 第二个函数执行具体的加密操作

我梳理AES_encrypt函数的执行逻辑如下:

  1. 函数首先执行AddRoundKey操作,对应初始轮运算;
  2. 初始轮之后共执行10轮运算,按照AES标准,最后一轮不应包含MixColumns操作,以下是其中9轮运算的代码片段:
#ifdef FULL_UNROLL
        /* round 1: */
        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
        /* round 2: */
        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
        /* round 3: */
        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
        /* round 4: */
  ........

根据代码注释,Te数组的定义如下:

Te0[x] = S [x].[02, 01, 01, 03];
    Te1[x] = S [x].[03, 02, 01, 01];
    Te2[x] = S [x].[01, 03, 02, 01];
    Te3[x] = S [x].[01, 01, 03, 02];

我存在两点疑问:

  • 代码中为何没有显式的SubBytes、ShiftRows操作?
  • 最后一轮似乎也执行了MixColumn操作,为何与标准AES流程不一致?或是我对代码的理解存在偏差?

解答

这是高性能AES实现的常规优化手段,OpenSSL的实现完全符合AES标准,你觉得缺步骤是因为代码做了深度合并优化,两个疑问分别解释:

为什么看不到单独的SubBytes、ShiftRows步骤

代码里的Te0到Te3是预计算生成的T盒(T-table),已经把多个轮操作合并进了查表逻辑:

  • 定义里的S[x]就是AES标准规定的S盒,查表取值的第一步就完成了SubBytes字节替换;
  • 代码里取状态值时做的移位、按位与操作(比如(s1 >> 16) & 0xff、s3 & 0xff),本质是把ShiftRows行移位要调整的字节位置,提前对应到了取不同状态字节的偏移上,不需要单独写循环做行移位操作;
  • 查表自带的固定系数伽罗瓦域乘法,就是MixColumns列混合的计算内容。

等于OpenSSL把原本要分三个独立步骤、跑多层循环的操作,全部合并成了4次查表加异或运算,运算量大幅降低,性能比完全按教材逐步骤写的朴素实现高很多。

为什么最后一轮看起来执行了MixColumns

你贴的只是前9轮的代码片段,最后一轮根本没有使用这几个带列混合系数的Te表。顺着完整代码往下翻就能看到,最后一轮是直接调用原始S盒做字节替换,配合移位操作,最后异或最后一轮轮密钥,完全跳过了MixColumns步骤,和标准流程完全一致,不存在实现偏差。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:15:31