3、加密算法选择:AES与SM4的对称加密原理归纳总结

讲到列级加密,第一步要解决的就是:**用什么算法来加密?**

你想想看,数据库里一列数据可能有几百万行,每行都要加解密。选错了算法,性能直接崩掉。我个人习惯,在对称加密这个领域,真正经得起生产考验的,就是两个流派:AES和SM4。

一个国际标准,一个国家标准。今天咱们把它们的核心原理掰开揉碎讲清楚。

3.1 为什么对称加密是列级加密的默认选项?

非对称加密(比如RSA)加解密太慢了。我做过压测,同样的硬件,RSA的吞吐量大概是AES的千分之一。列级加密面对的是高频、小数据块的读写场景,非对称根本扛不住。

对称加密就不一样。加密和解密用同一把密钥,硬件加速支持好,性能损耗可控。说白了,在工作中我基本只考虑对称加密方案。

核心原则:列级加密首选对称算法。用非对称做列级加密,不是技术选型,是给自己挖坑。

3.2 AES:对称加密界的“老大哥”

3.2.1 算法结构

AES全称Advanced Encryption Standard,分组长度固定128位。密钥长度支持128位、192位、256位。

它本质是一个替换-置换网络(SPN)。说白了,就是先把数据切成块,然后一轮一轮地做替换和位置打乱。轮数取决于密钥长度:10轮(128位)、12轮(192位)、14轮(256位)。

每一轮干四件事:

  1. 字节代换(SubBytes):用一个S盒查表,把每个字节换成另一个。
  2. 行移位(ShiftRows):把矩阵的每一行向左循环移位。
  3. 列混合(MixColumns):对每一列做矩阵乘法,扩散数据。
  4. 轮密钥加(AddRoundKey):把这一轮的密钥和状态矩阵异或。

最后一轮会跳过列混合这一步。

3.2.2 密钥扩展

AES的密钥扩展算法挺精巧。从原始密钥生成每一轮需要的轮密钥。我记得有一次排查问题,发现密钥扩展代码没初始化好,导致所有加密结果都一样——那是个非常隐蔽的bug。

// AES-128密钥扩展伪代码(仅示意)
void KeyExpansion(byte[] key, word[] w) {
    for (int i = 0; i < 4; i++)
        w[i] = (key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]);

    for (int i = 4; i < 44; i++) {
        word temp = w[i-1];
        if (i % 4 == 0)
            temp = SubWord(RotWord(temp)) ^ Rcon[i/4];
        w[i] = w[i-4] ^ temp;
    }
}

3.2.3 工作模式

AES本身只是一个分组密码。实际使用时,需要套一个工作模式。

模式 特点 列级加密推荐度
ECB 每个分组独立加密,相同明文生成相同密文 不推荐,会暴露数据模式
CBC 前一个密文分组参与当前分组加密 推荐,但需随机IV
GCM 认证加密模式,同时提供完整性校验 强烈推荐,列级加密首选
CTR 流密码化,可并行加解密 适合高性能场景

我在项目里踩过一个坑——一开始用了ECB模式,结果密文列的统计分布直接暴露了原文的业务规律。嗯,这里要注意,ECB不能用在列级加密里。

3.3 SM4:国密标准,设计逻辑也很清楚

3.3.1 算法结构

SM4是国家密码管理局发布的对称加密标准。分组长度也是128位,密钥长度128位。

它的结构是**不平衡的Feistel网络**。什么意思呢?就是把数据分成两半,每一轮只处理一半,然后左右交换。SM4一共32轮。

每轮的核心操作:

  1. S盒置换:用一个8进8出的S盒做非线性替换。
  2. 线性变换L:一个32位的左右移位和异或操作。
  3. 轮密钥加:把轮密钥和当前数据异或。

我发现SM4的线性变换比AES的列混合更好理解,纯移位加异或,没有矩阵乘法。硬件实现成本更低。

3.3.2 密钥扩展

SM4的密钥扩展比AES简单很多。不需要轮常数Rcon,直接通过S盒和线性变换生成32个轮密钥。

// SM4密钥扩展核心逻辑(伪代码)
for (int i = 0; i < 32; i++) {
    K[i+4] = K[i] ^ T'(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i]);
}
// 轮密钥 rk[i] = K[i+4]

T'是一个合成变换,包含S盒和线性变换。CK是固定的系统参数。

一个小技巧:如果你要在硬件上实现SM4,密钥扩展和加解密可以共用S盒,节省大量门电路。

3.4 AES vs SM4:混合使用的场景

很多同行问我:到底选AES还是SM4?我的回答是:**看合规要求**。

  • 出海业务或国际系统:AES-256-GCM是事实标准,硬件加速最成熟。
  • 国内政务、金融、关键基础设施:必须要用SM4,这是合规红线。
  • 混合架构:我见过一个方案,AES做数据加密,SM4做密钥加密——两者互补。

从安全强度看,两者经过充分密码分析,128位密钥级别都满足当前商业场景的要求。量子计算时代另说,那是后话了。

避坑提示:我曾经遇到一个团队,自认为“增强安全”,把AES和SM4串起来用了两遍。结果性能降了60%,安全性没有任何实质提升。套两层对称加密,纯属浪费CPU。

3.5 知识体系:对称加密核心逻辑图

下面这张图把AES和SM4的对比逻辑画清楚了。你可以对照看,两种算法的流程到底差在哪:

AES与SM4对称加密原理对比图 对称加密核心逻辑:AES与SM4对比 AES 加密流程 明文分组(128位) + 密钥(128/192/256位) 初始轮密钥加(AddRoundKey) 轮函数(10/12/14轮) SubBytes → ShiftRows → MixColumns AddRoundKey(最后一轮无MixColumns) 输出密文分组 SM4 加密流程 明文分组(128位) + 密钥(128位) 初始数据处理(分成4个32位字) 32轮Feistel结构迭代 S盒置换 → 线性变换L → 异或 密钥扩展:T'变换 + CK参数 输出密文分组(反序处理) 轮数 AES: 10-14 SM4: 32 结构 AES: SPN SM4: Feistel 共同点:分组128位 | 轮密钥加 | S盒非线性替换 | 可硬件加速

3.6 关键指标横向对比

下面这张表,我建议你存下来。选型的时候直接对照看,一目了然:

对比维度 AES SM4
标准发布 2001年,NIST 2012年,中国国密局
分组长度 128位 128位
密钥长度 128/192/256位 128位
算法结构 SPN(替换-置换网络) 不平衡Feistel网络
轮数 10/12/14轮 32轮
最慢模式 CBC(不可并行) CBC(不可并行)
硬件加速 AES-NI指令集,极快 依赖软件实现,性能可接受
合规 国际通用 国内政务/金融强制要求
推荐工作模式 GCM(认证加密) GCM或CBC+HMAC
我的个人经验:如果硬件支持AES-NI,AES-256-GCM的性能可以做到接近内存带宽。SM4虽然没有专用指令,但在现代CPU上跑纯软件实现,单条数据的加解密延迟也能控制在微秒级。列级加密完全够用。

3.7 关于密钥管理的题外话

算法选好了,密钥怎么存?我在实际项目中见过太多人把密钥硬编码在代码里,或者放在配置文件中。嗯,这里必须强调:密钥必须独立于应用存储。

我的建议是:

  • 使用专用的密钥管理服务(KMS)
  • 密钥轮换周期不超过90天
  • 每个列使用独立的数据加密密钥(DEK),由主密钥加密存储

这部分后面章节会展开讲。今天你只要记住:算法是安全的基础设施,但密钥管理才是真正的防线。