3. 常见加密算法:AES、RSA、ECC 与国密 SM2/SM4

聊到应用层加密,算法选型是绕不开的一步。我个人习惯把算法先分成两类:对称加密和非对称加密。搞清楚了这两类,SDK 的代码结构基本就定了一半。

核心原则:对称加密快,适合加密大数据;非对称加密安全,适合交换密钥。实际 SDK 里,两者常配合使用。

3.1 对称加密:AES 与 SM4

对称加密,说白了就是加密和解密用同一把钥匙。你想想,快递柜的取件码就是典型的对称密码——输入同一串数字,门开了。

AES(高级加密标准)是国际公认的对称加密标杆。我在项目中遇到过最坑的事,就是有人把 AES 的密钥硬编码在 APK 的 so 文件里,反编译一下就直接看到了。嗯,这里要注意:AES 本身没问题,问题全在密钥管理。

AES 模式 是否需要 IV 安全性 典型场景
ECB 否 低(同一明文块输出相同) 不推荐,仅兼容遗留系统
CBC 是 较高 文件加密、数据库字段
GCM 是 高(附带认证) 网络传输、API 响应加密
CTR 是 较高 流式数据、实时通信
避坑指南:我曾经见过一个项目用 AES-ECB 加密用户手机号,结果相同前缀的手机号密文一模一样,直接暴露了用户的号码段。个人建议,除非你确定数据没有重复块,否则别用 ECB。优先选 GCM,自带认证,省去额外算 MAC 的麻烦。

SM4 是国家密码管理局发布的对称加密标准,它的密钥长度也是 128 位,分组大小和 AES 一样。你可能会问,那干嘛不直接用 AES?原因很简单:合规。金融、政务、关键基础设施的系统,现在明文要求必须用国密。SM4 在算法强度上不输 AEs,但国内的硬件和软件生态对它的优化还在追赶。

重要提示:SM4 的中国官方标准是 GB/T 32907-2016。如果你的 SDK 要对接政府项目或银行系统,SM4 是必选项。我在实际集成中遇到的常见坑是:算法库的 SM4 实现默认模式是 ECB,需要手动切换成 CBC 或 GCM 模式。

3.2 非对称加密:RSA 与 ECC

非对称加密用一对钥匙——公钥加密,私钥解密。你想想看,把公钥公开给所有人,大家都能给你发加密消息,只有你能解开。这在密钥分发上解决了对称加密的“配送难题”。

RSA 是我最早接触的非对称算法。它的安全性依赖于大整数分解的数学难题。1024 位的 RSA 现在已经不安全了,行业标准是 2048 位。我曾经在物联网项目里用 2048 位 RSA,结果设备 CPU 跑一次签名用了 800 毫秒,老板直接问“你是不是在给用户做进度条动画?”

ECC(椭圆曲线加密) 用更短的密钥达到相同安全级别。比如 256 位的 ECC 相当于 3072 位的 RSA。为什么会这样?椭圆曲线上的离散对数问题目前还没有高效破解办法。我在移动端 SDK 设计里,只要条件允许,会优先选 ECC 做签名和密钥协商,性能开销小很多。

算法 密钥长度(安全级别 128 位) 签名耗时(参考值) 主要瓶颈
RSA 3072 位 ~5ms(私钥签名) 密钥生成慢、密文膨胀
ECC 256 位 ~1ms 曲线参数选择复杂
SM2 256 位 ~1.2ms 国产硬件加速有限
实战经验:RSA 不只是慢,它的密文长度还膨胀得厉害。比如用 2048 位密钥加密 32 字节的 AES 密钥,输出密文是 256 字节。而 ECC 的 SM2 加密同一数据,输出大约 80 字节。网络传输中,压缩数据量的好处很明显。

3.3 国密算法:SM2 / SM4 / SM3

国密系列不是一套单独的名字,而是一套完整的密码体系。包括对称加密 SM4、非对称加密 SM2、哈希 SM3。为什么单独拎出来讲?因为国内监管对这部分有强制要求,而且它们在设计上与国际标准有差异。

  • SM2:基于椭圆曲线,公钥 64 字节,私钥 32 字节。它的签名算法和 ECDSA 不同,验签时必须使用国密标准的派生函数。我在对接某地方银行时,对方要求 SM2 签名必须用 sm2sign-with-sm3 模式,而不是随便传个摘要进去。
  • SM4:前面讲过了,注意模式选择。
  • SM3:国密哈希算法,输出 256 位。它的压缩函数和 SHA-256 不同,但安全性相当。SM3 在国密体系里用来做消息认证和 SM2 签名的摘要。
关于算法库:千万别自己去实现国密算法,轮子已有。Java 可以用 Bouncy Castle,Android 可以用腾讯的 TMF 或华为的 hwsecuritykit。iOS 可以去 Github 上找 gmssl 的 Swift 封装。我们曾踩过一个坑:自实现 SM2 点乘的一个常数写错了,上线后某个机型验签总是失败。
许可证注意:Bouncy Castle 对国密的支持在 1.60 版本之后才完整。如果你的项目还在用 1.50,小心会遇到 SM2 签名长度不对的 bug。我曾经排查了一整天,最后发现是 jar 包版本太老。

3.4 这些算法在 SDk 里怎么选?

选型不是拍脑袋,我一般按这个决策链条来走:

  1. 先看合规要求:客户或监管是否强制国密?是,直接上 SM2 + SM4 + SM3。
  2. 再看运行环境:目标平台安全芯片有硬件加速吗?AES-NI 指令集可让加解密快 10 倍。如果没有,考虑 ECC 和 SM2 也能接受。
  3. 然后看传输模式:短数据交互(比如握手、令牌交换)用非对称;长数据(响应体、大文件)用对称。
  4. 最后看密钥生命周期:记住,算法只是安全链条的一环。密钥存哪、怎么轮换,比选哪个算法更重要。
最终建议:如果你的 SDK 不涉及合规要求,我建议你默认用 AES-256-GCM + ECDH 做密钥交换。这套组合在安全、性能、通用性上最均衡。如果客户明确要求国密,那就直接走 SM4-GCM + SM2 密钥协商。

好了,这就是加密算法的基础认知。每种算法都有它的脾气——AES 快但管理密钥麻烦,RSA 安全但是吃性能,ECC 和 SM2 很省资源但得注意参数合规。你实际开发时,别光看算法名字,还要看它被封装成什么样子。我在下一步会带你看,SDK 内部是怎么把这些算法组装成可调用的 API 的。