4、移动端加密方案选择:AES、RSA、国密SM系列
做移动端加密,第一步不是选库,而是选算法。我记得刚带项目时,团队里争论了很久“到底用AES还是RSA”。其实两者根本不是一个赛道——AES是对称加密,RSA是非对称,用途完全不同。后来我们引入了国密SM系列,才发现国产方案在某些场景下反而更顺手。
这节我带你快速过一遍三种主流方案的核心差异、适用场景,以及我在集成时的真实踩坑记录。
4.1 对称加密:AES 与 SM4
对称加密,说白了就是加密和解密用同一把钥匙。你想想看,如果两个人的钥匙一样,那传递钥匙的过程就必须非常安全。移动端里,钥匙通常存在本地或通过安全信道分发。
| 特性 | AES (128/256) | SM4 (国密) |
|---|---|---|
| 算法来源 | 美国NIST标准,全球通用 | 中国国密标准,商用密码算法 |
| 密钥长度 | 128 / 192 / 256 位 | 128 位 |
| 分组模式 | ECB / CBC / GCM 等 | ECB / CBC / CTR / GCM 等 |
| 硬件加速 | 主流 SoC 内置 AES-NI | 部分国产芯片有 SM4 硬加速 |
| 移动端支持 | iOS CommonCrypto / Android Crypto 原生 | 需引入 GMSSL / 腾讯 Tmio 等库 |
我的经验:如果是面向海外市场,优先 AES-GCM,自带认证加密,不用自己拼 HMAC。我在一个跨境支付 App 里用过 AES-CBC + HMAC,结果每次都要拼接校验,后来全改成 GCM,代码少了一半。
SM4 的亮点是国密认证。如果你负责的 App 要过“等保”或入驻政府项目,SM4 几乎是必选项。但要注意:iOS 原生不支持 SM4,需要用交叉编译的动态库,体积会增加 2-3 MB。
4.2 非对称加密:RSA 与 SM2
非对称加密有两个钥匙——公钥和私钥。你在移动端存公钥,服务端持私钥。这样就算客户端代码被抓包,黑客也拿不到私钥,没法解密。
| 特性 | RSA (2048/4096) | SM2 (国密椭圆曲线) |
|---|---|---|
| 算法类型 | 大整数分解 | 椭圆曲线 (ECC) |
| 密钥长度 | 2048 / 4096 位 | 256 位 (等效 RSA 3072) |
| 加密性能 | 慢,加密块小(密钥长度减11字节) | 快,密文短 |
| 签名验签 | PKCS1 v1.5 或 PSS | SM2 签名 (类似 ECDSA) |
| 合规性 | 全球通用 | 中国国密强制要求 |
这里有个常见误区:很多人用 RSA 加密大量数据。但我必须提醒你,RSA 不适合加密长消息。2048 位的密钥最多加密 245 字节。我之前见过一个小贷 App,直接用 RSA 加密整个 JSON 报文,结果拿不到解密——溢出了。正确的做法是用 RSA 加密 AES 的密钥,再用 AES 加密实际数据。
避坑指南:我曾经接手过一个 SDK,它用 RSA 直接加密几百 KB 的图片。每次加密耗时 3 秒以上,还经常报错。后来改成“随机 AES Key + RSA 加密该 Key”的方案,速度提升了几十倍。
SM2 的密钥长度只有 256 位,但安全强度跟 RSA 3072 差不多。移动端算签名时,SM2 比 RSA 快 5-10 倍。如果你的 App 需要频繁签名(比如每次请求都要签名),SM2 会明显流畅。
4.3 国密 SM3:哈希的替代方案
大部分移动端项目用 SHA-256 做哈希。但国密体系里,SM3 是哈希算法,输出 256 位摘要。它跟 SHA-256 性能接近,但国内合规场景下必须用 SM3。
我建议这样用:
- 普通项目:SHA-256 就够用,iOS/Android 都原生支持
- 合规项目:SM3 替换所有哈希调用
- 注意:SM3 不能单独拿来加密,它只提供完整性校验
4.4 移动端选型决策流程
我画了一张图,帮你在不同场景下快速选型。先从“是否合规”入手,然后看数据量和性能要求。
4.5 混合加密方案:最佳实践
无论你用哪一套算法,移动端推荐的做法都是混合加密。核心逻辑就三步:
- 客户端生成一个随机的 AES(或 SM4)密钥,称为“会话密钥”
- 用服务端的公钥(RSA 或 SM2)加密这个会话密钥
- 用会话密钥加密实际请求/响应数据,并附带 HMAC(或 SM3)校验
这样既保证了大数据量的加密速度(对称加密快),又解决了密钥分发问题(非对称加密公钥无需保密)。我在集成金融 SDK 时一直用这套结构,从未出过安全问题。
关键点:会话密钥每次请求都随机生成。千万别复用上一次的密钥,否则一旦泄露,历史数据全完蛋。我习惯用 SecRandomCopyBytes(iOS)或 SecureRandom(Android)生成 32 字节的随机数。
4.6 避坑清单
- 别用 ECB 模式:我曾经在一次内部审计中发现团队用了 AES-ECB,结果同样的密文块出现频率被统计出来,漏洞很大。后来全改成 GCM 或 CBC + HMAC。
- 公钥固定(Pinning):如果你用 RSA 或 SM2,客户端一定要把服务端公钥写死在 App 里,不能信任任何第三方 CA 证书。我见过一个 App 因为 CA 被中间人替换,所有加密形同虚设。
- 国密库选择:我推荐 GmSSL(开源)或腾讯的 Tmio。注意版本:2020 年以后 GM/T 标准更新过 SM3 的填充细节,老库可能不兼容。
- 性能测试:SM4 在没硬加速的旧手机上,加密 1 MB 数据会多花 30-50 ms。如果你的 App 需要频繁加密大量图片或视频,做一次压测再上线。
选择加密方案,没有的对错。核心看三点:合规要求、数据敏感度、性能开销。记好我上面那张决策图,再加上混合加密的骨架,你在移动端就稳了。剩下的就是写代码时小心一点——嗯,别把密钥写死在代码字符串里。