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位)。
每一轮干四件事:
- 字节代换(SubBytes):用一个S盒查表,把每个字节换成另一个。
- 行移位(ShiftRows):把矩阵的每一行向左循环移位。
- 列混合(MixColumns):对每一列做矩阵乘法,扩散数据。
- 轮密钥加(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轮。
每轮的核心操作:
- S盒置换:用一个8进8出的S盒做非线性替换。
- 线性变换L:一个32位的左右移位和异或操作。
- 轮密钥加:把轮密钥和当前数据异或。
我发现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是固定的系统参数。
3.4 AES vs SM4:混合使用的场景
很多同行问我:到底选AES还是SM4?我的回答是:**看合规要求**。
- 出海业务或国际系统:AES-256-GCM是事实标准,硬件加速最成熟。
- 国内政务、金融、关键基础设施:必须要用SM4,这是合规红线。
- 混合架构:我见过一个方案,AES做数据加密,SM4做密钥加密——两者互补。
从安全强度看,两者经过充分密码分析,128位密钥级别都满足当前商业场景的要求。量子计算时代另说,那是后话了。
3.5 知识体系:对称加密核心逻辑图
下面这张图把AES和SM4的对比逻辑画清楚了。你可以对照看,两种算法的流程到底差在哪:
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 |
3.7 关于密钥管理的题外话
算法选好了,密钥怎么存?我在实际项目中见过太多人把密钥硬编码在代码里,或者放在配置文件中。嗯,这里必须强调:密钥必须独立于应用存储。
我的建议是:
- 使用专用的密钥管理服务(KMS)
- 密钥轮换周期不超过90天
- 每个列使用独立的数据加密密钥(DEK),由主密钥加密存储
这部分后面章节会展开讲。今天你只要记住:算法是安全的基础设施,但密钥管理才是真正的防线。