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 移动端选型决策流程

我画了一张图,帮你在不同场景下快速选型。先从“是否合规”入手,然后看数据量和性能要求。

移动端加密方案选型决策图 是否需要合规? 是 → 选用国密 SM 系列 否 → 通用算法 AES+RSA 加密大数据 → SM4 + SM3 校验 签名 / 密钥交换 → SM2 + SM3 加密大数据 → AES (GCM 模式) 签名 / 密钥交换 → RSA + SHA-256 提醒:国密方案需集成第三方库(如 GmSSL),注意 iOS 代码签名的安全策略 混合方案:非对称加密对称密钥,对称加密实际数据(适用于两分支)

4.5 混合加密方案:最佳实践

无论你用哪一套算法,移动端推荐的做法都是混合加密。核心逻辑就三步:

  1. 客户端生成一个随机的 AES(或 SM4)密钥,称为“会话密钥”
  2. 用服务端的公钥(RSA 或 SM2)加密这个会话密钥
  3. 用会话密钥加密实际请求/响应数据,并附带 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 需要频繁加密大量图片或视频,做一次压测再上线。

选择加密方案,没有的对错。核心看三点:合规要求、数据敏感度、性能开销。记好我上面那张决策图,再加上混合加密的骨架,你在移动端就稳了。剩下的就是写代码时小心一点——嗯,别把密钥写死在代码字符串里。