2. 加密算法选型:对称 vs 非对称,AES、RSA、SM 系列怎么选

说到加密算法选型,很多团队上来就问我:"到底用 AES 还是 RSA?国密是不是必须的?"

说实话,这个问题没有标准答案。得看你的数据生命周期、性能预算和合规要求。

我自己踩过的坑就不少。早些年做银行核心系统迁移,直接用了 RSA 加密大字段,结果每天几千万条记录,加解密耗时直接打满 CPU,最后被迫切回对称加密。嗯,选型这事儿,一步错后面全是补丁。

2.1 对称加密 vs 非对称加密:核心差异

对称加密,说白了就是加密和解密用同一把钥匙。速度快,适合批量数据。非对称加密用公钥/私钥对,慢但解决了密钥分发问题。

你想想看:如果两个人要通信,对称加密需要提前把密钥安全地传给对方;非对称加密只需要公开公钥,私钥自己留着。应用场景完全不同。

维度对称加密非对称加密
密钥一个密钥,加解密共用公钥+私钥,成对出现
速度快(硬件加速后可达 GB/s 级别)慢(慢 2~3 个数量级)
典型用途大数据量加密、存储加密密钥交换、数字签名、小数据加密
密钥管理分发困难,需要安全通道公钥公开,私钥本地保护
抗量子计算AES-256 仍较安全RSA-2048 易被 Shor 算法破解
我的习惯:实际项目里,99% 的数据加密用对称密钥搞定。非对称只用来加密对称密钥本身(即混合加密)。这样性能和安全都能兼顾。

2.2 AES:对称加密的工业标准

AES 是目前最通用的对称加密算法。支持 128/192/256 位密钥,推荐直接用 AES-256。我遇到过有些老系统还在用 3DES,迁移时全部切换为 AES,性能提升明显。

选择 AES 时要注意工作模式:

  • ECB 模式:千万别用。相同的明文块产出相同密文块,有统计规律漏洞。我曾经在一个金融日志加密项目中因为用了 ECB,导致密文被攻击者通过模式匹配识别出交易类型,后来全部重做。
  • CBC 模式:需要 IV(初始化向量),每次加密 IV 要随机且不重复。适合文件加密。
  • GCM 模式:同时提供加密和完整性校验,推荐用于网络传输。我的大部分新项目都用 AES-256-GCM。
# Python 示例:AES-256-GCM 加解密
from Crypto.Cipher import AES
import os

key = os.urandom(32)           # 256 位密钥
nonce = os.urandom(12)         # GCM 推荐 12 字节 nonce
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
ciphertext, tag = cipher.encrypt_and_digest(b"存量字段加密迁移数据")

# 解密
cipher2 = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher2.decrypt_and_verify(ciphertext, tag)
print(plaintext.decode())
我曾经踩过的坑:用了固定的 nonce(IV)导致密文在重放攻击下完全失效。后来强制用数据库自增 ID + 时间戳拼接生成 nonce,且每个 key 只允许使用一次 nonce 组合。

2.3 RSA:非对称加密的老大哥

RSA 基于大整数分解难题。密钥长度至少 2048 位,建议 3072 或 4096。但它的性能真的堪忧——加密 117 字节数据需要 2ms 左右,而 AES 加密 1MB 数据也不过几微秒。

实际中 RSA 只用来加密对称密钥(256 位 AES 密钥),或者做数字签名。我见过有人直接拿 RSA 加密几 KB 的 JSON 字段,结果接口响应时间从 50ms 飙升到 3s 以上,这就是典型的反模式。

RSA 还有一个大问题:抗不住量子计算。虽然目前量子计算机还没到实用规模,但如果你做的是长期存档(比如医疗数据保存 50 年),建议现在就考虑后量子密码迁移。

2.4 SM 系列国密算法:国内合规刚需

国密算法是国家密码管理局发布的算法标准。金融、政务、关键基础设施项目经常被要求必须使用。

  • SM2:椭圆曲线公钥密码,对标 RSA,但密钥更短(256 位)且性能更好。我个人觉得 SM2 在签名场景比 RSA 快 3~5 倍。
  • SM3:密码杂凑函数,类似 SHA-256。输出 256 位哈希值。注意 SM3 不是 SHA-256,不能直接互相替换。
  • SM4:对称加密,类似 AES-128。密钥长度 128 位,分组 128 位,算法公开。国内很多数据库加密扩展(如 MySQL 的 SM4 插件)已经可用。

选型时要注意:SM2/SM4 已经被纳入 OpenSSL 1.1.1+ 和 GMSSL,无需自己实现。但一些第三方库的国密实现可能有性能瓶颈(比如部分 Java 库的 SM4 速度只有 AES 的一半)。建议上生产前做压测。

算法密钥长度分类典型替代对象性能参考
AES-256256 bit对称—基准(最快)
SM4128 bit对称AES-128约 AES 的 60%~80%
RSA-20482048 bit非对称—慢(签名/验签 1~3ms)
SM2256 bit非对称RSA-2048快于 RSA,与 ECDSA 相当
SM3输出 256 bit哈希SHA-256略慢于 SHA-256

2.5 如何选择:我的决策框架

我会从三个维度做决策:

  1. 数据量:单个字段超过 100 字节,优先对称。
  2. 密钥交换:如果需要在线分发密钥,必须套非对称。
  3. 合规:项目面向政企、金融且在中国境内,先确认是否需要国密资质。

下面这张图是我实际项目中整理出的选型决策树,你可以直接参考。

加密算法选型决策树 数据需要加密吗? 需要安全分发密钥吗? 非对称加密 对称加密 用于密钥交换 / 数字签名 建议:SM2 或 RSA-2048+ 批量数据加密 建议:AES-256-GCM 或 SM4 有合规要求(金融/政务)? 强制使用国密 SM2 + SM3 + SM4 组合 可采用国际算法 AES-256-GCM + RSA/ECDSA 注意:如果长期数据(>10年),建议考虑后量子加密预备,如 AES-256 + 格密码。

总结推荐:

  • 一般互联网项目:AES-256-GCM 加密数据 + RSA 交换密钥,简单高效。
  • 政务/金融国内项目:SM4 加密数据 + SM2 数字签名,合规无忧。
  • 既有系统迁移:优先保持原算法兼容,在双写阶段逐步替换为更安全的算法(比如从 3DES 升级到 AES)。
我曾经翻车的一次经历:自认为选了最安全的 AES-256-CBC,但没考虑 IV 重用问题。测试环境一切正常,上线后因为并发库使用了伪随机数种子,导致不同线程生成了相同的 IV。解密前几条记录都成功,后面全乱码。后来强制用 urandom + 数据自增 ID 做 nonce 唯一性保障。这个贴士值得你记下来。