第3章 加密引擎选型:AES/GCM、RSA/EC、ChaCha20性能对比、密钥长度与模式选择、Android原生加密API边界

加密引擎选型是数据保护组件设计的核心决策。本章从组件边界出发,分析 AES/GCM、RSA/EC、ChaCha20 三种引擎在 Android 环境下的性能特征、密钥长度与模式选择策略,并界定 Android 原生加密 API 的业务边界,为架构师提供可落地的选型框架。

加密引擎选型决策流程图 业务场景分析 威胁模型评估 性能基线测试 AES/GCM ChaCha20 RSA/EC 密钥长度128/256 IV/Nonce大小 关联数据(AAD) 填充/PKCS#1 Android原生加密API边界 javax.crypto.Cipher · KeyStore · KeyGenParameterSpec · Conscrypt Provider

引擎性能对比

特性AES/GCMChaCha20/Poly1305RSA/EC (Elliptic Curve)
对称/非对称对称加密对称加密非对称加密
算法类型分组加密 (128-bit block)流加密公钥加密/密钥协商
典型密钥长度128, 192, 256 bit256 bit2048-4096 bit (RSA) / 256-521 bit (EC)
认证模式GCM (AEAD)Poly1305 (AEAD)无内建AEAD,需配合CBC+HMAC或OAEP
硬件加速ARMv8 AES指令 (40-60 MB/s)无专用指令 (15-30 MB/s)无通用加速 (慢10-100x)
IV/Nonce大小12 byte (推荐)12 byte无
主要用途大数据量对称加密/存储移动端低功耗加解密密钥交换/数字签名/证书
Android API 级别限制API 19+ (KeyGenParameterSpec API 23+)API 21+ (Conscrypt Provider)API 1+ (RSA), API 23+ (EC KeyStore)

决策原则:对称加密首选 AES/GCM(硬件加速稳定);追求极低延迟与电池友好场景(如 IoT、实时通信)可选 ChaCha20;RSA/EC 仅用于密钥封装、签名和身份认证,不直接加密业务数据。

密钥长度与模式选择

引擎推荐密钥长度加密模式填充方案备注
AES/GCM256 bit (默认)GCM (AEAD)不需要填充IV 12 byte,tag 16 byte;注意 IV 不可重复
ChaCha20/Poly1305256 bitXChaCha20 (扩展 nonce) 或标准不需要填充Nonce 12 byte (标准) 或 24 byte (XChaCha20)
RSA/ECRSA 3072 bit / EC P-256ECB (单块) / ECDH (密钥交换)OAEP (推荐) 或 PKCS#1 v1.5禁止使用 ECB 模式加密多个数据块;EC 不直接加密

实践建议:对于对称加密统一使用 AES/GCM/NoPadding,密钥通过 KeyGenParameterSpec.Builder 的 setKeySize(256) 指定;非对称加密仅用于密钥封装(RSA/ECIES)或签名(ECDSA)。

Android 原生加密 API 边界

Android 提供 javax.crypto.Cipher 作为加密操作入口,底层通过 Provider 架构解析算法字符串(如 "AES/GCM/NoPadding")。边界条件包括:

  • 算法字符串格式:"算法/模式/填充",如 "ChaCha20" 在 API 21+ 被映射为 Conscrypt Provider 的流模式。
  • 密钥材料存储:建议使用 Android KeyStore 生成和存储密钥,禁止将密钥明文写入 SharedPreferences 或文件中。
  • KeyGenParameterSpec 限制:API 23+ 支持 setBlockModes("GCM") 和 setEncryptionPaddings("NoPadding"),但 ChaCha20 不能通过 KeyStore 生成密钥,只能通过 KeyGenerator 或直接传入字节。
  • Conscrypt Provider 优先级:系统默认 Provider 可能因厂商定制而缺失 ChaCha20,建议显式指定 Cipher.getInstance("ChaCha20", "Conscrypt")。
  • NV/Nonce 管理:GCM 要求每次加密使用唯一 IV,推荐使用 SecureRandom 生成 12 byte 并随密文存储。

风险点:使用 RSA/ECB/PKCS1Padding 加密长数据会导致 IllegalBlockSizeException;GCM 的 GCMParameterSpec tag 长度若小于 128 bit 可能被降级攻击。

信任链路与密钥生命周期

从密钥生成到销毁构成一条完整的信任链路:

  1. 密钥生成:通过 KeyPairGenerator 或 KeyGenerator 在 KeyStore 内创建,保证私钥不可导出。
  2. 密钥使用:Cipher.init() 时指定 KeyStore.SecretKeyEntry 或 PrivateKeyEntry。
  3. 密钥备份/迁移:使用 AES 包装密钥(Key Wrapping)后导出,要求包装密钥本身在 TEE 中管理。
  4. 密钥销毁:调用 KeyStore.deleteEntry();若密钥在 TEE 中,需等待系统重启或调用厂商专用 API。

选型权衡矩阵

场景推荐引擎密钥长度模式理由
本地数据库字段加密AES/GCM256 bitGCM/NoPaddingAEAD 保证完整性,硬件加速快
实时语音/视频加密ChaCha20256 bitChaCha20流加密低延迟,无填充开销
HTTPS 证书/API 签名RSA 或 EC3072 bit (RSA) / P-256 (EC)OAEP/ECDSA兼容性优先,EC 性能更优
密钥交换与会话密钥生成ECDHE + AES/GCMP-256 + 256 bitECDH + GCM前向安全性,业界标准
离线内容保护(DRM)AES/GCM128 bit (合规)GCM/NoPadding兼容 Widevine L3 要求

落地步骤

  1. 确定目标场景:是存储加密、传输加密还是密钥封装?据此选择对称或非对称。
  2. 建立性能基线:在目标设备上(至少 Android 10+ 和低端机)跑 AES/GCM、ChaCha20 的加密 1MB 数据耗时,记录 5 次测量中位数。
  3. 配置 KeyStore:使用 KeyGenParameterSpec.Builder 设置 setKeySize(256)、setBlockModes("GCM"),并在 setIsStrongBoxBacked(true) 如果设备支持。
  4. 实现 IV 管理:加密时将 IV 拼接在密文前(prefix 12 byte),解密时先提取 IV。
  5. 集成单元测试:覆盖密钥生成、加解密、签名验证、密钥删除全流程,包括异常注入(如篡改 IV、tag 错误)。
  6. 验证兼容性:在 API 26、30、33 模拟器上运行 CTS-like 测试,确认无 Provider 缺失。

验收标准

检查项通过条件验证方法
密钥不可导出KeyStore 私钥/secret 无法通过 getEncoded() 获取尝试调用,应抛出 KeyStoreException
IV 唯一性对同一密钥加密 10⁶ 次无重复 IV使用 SecureRandom 生成 IV,统计分析
AEAD 完整性篡改密文后解密抛出 AEADBadTagException单元测试中修改最后一个密文字节
性能基线AES/GCM 加密 1MB < 50ms (中端设备)基准测试脚本,记录5次中位数
Provider 回退所有引擎在 API 21-33 上均正常工作多版本模拟器测试,失败时打印异常堆栈
密钥轮换旧密钥加密的数据能被新密钥解密并存档实现打包密钥机制,验证迁移路径