如何安全使用加密套件?
对称加密
- 首选 Chacha20-Poly1305 和 AES-GCM 算法(AEAD类算法)
- 不支持 AES-GCM 或 Chacha20-Poly1305 的场景下使用 AES-CBC,避免 ECB、CTR、CFB、OBF 模式
- 避免64bit块加密算法,例如 blowfish、TEA 等
- 不要使用RC4
- 不要自行设计加密算法,除非你在密码学领域是整个行业公认的专家
- 不要多次循环加密,加密强度取决于加密算法、秘钥长度,以及正确的实现加密过程。循环加密对加密强度没有实际意义的帮助
原因
- Chacha20-Poly1305,AEAD类算法;绕开了目前所有已知的漏洞;面向移动互联网优化;ARM架构上性能更佳
- AES-GCM,AEAD类算法;TLS 1.3 draft主要的算法;工业标准;现代CPU有AES-GCM的硬件指令
对称秘钥长度
- 对称秘钥长度不能低于128 bit,也即16字节
- 长度超过256 bit的对称秘钥没有实际意义
- 对称加密、RSA、ECC三种不同类型的算法中,同样的秘钥长度安全性也不同,下面表格中列出来同样强度情况下,对应不同算法的秘钥长度
- 对称秘钥生成规则参考本文的 "随机数生成规范"
Symmetric Key Size (bits) |
RSA and DH Key Size (bits) |
Elliptic Curve Key Size (bits) |
---|---|---|
80 | 160 | 1024 |
112 | 224 | 2048 |
128 | 256 | 3072 |
192 | 384 | 7680 |
256 | 521 | 15360 |
以上数据来自:https://www.globalsign.com/en/blog/elliptic-curve-cryptography/
AES-CBC实现注意事项
必须使用符合加密算法安全的随机数生成器,cryptographically strong random number generator (RNG):https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator
- iv必须随机生成,不能固定;生成规则参考本文的 "随机数生成规范"
- 避免用秘钥代替iv
- 避免用 stdlib 系列伪随机数
随机数生成规范
随机生成的iv或者nonce要采用/dev/urandom生成,或者采用基于/dev/urandom实现的随机数生成器
- 避免采用 stdlib 系列伪随机数
- 避免 havaged,prngs,egd 等
- 避免 /dev/random ,会因为熵池噪声数据不足而阻塞几秒甚至是十几秒,严重影响性能,参考:https://zh.wikipedia.org/zh-cn//dev/random
成熟的Library推荐
- iOS 可以采用 Randomization Services Reference:https://developer.apple.com/library/ios/documentation/Security/Reference/RandomizationReference/
- Android & 服务端Java可以使用 SecureRandom:https://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html
- 其他场景:推荐使用libsodium库,或NaCL库封装,或者直接读取 /dev/urandom
非对称加密
建议椭圆曲线,避免RSA
主要考虑前向安全性、椭圆曲线性能,以及现代计算机对RSA攻击能力逐年提升
HMAC算法
使用SHA2类的算法:SHA-256,SHA-384,SHA-512,SHA512/256等
避免 SHA-1、MD5、MD6
加密库选择
- iOS:建议使用原生的 Common Crypto,来自 Apple 的建议:https://developer.apple.com/cryptography/ ;避免使用 OpenSSL,原因是 OpenSSL 接口不友好、漏洞频发、版本升级时向下兼容性不好
- Android:建议使用 javax.crypto,https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/package-summary.html
- PC & Mac: 优先使用libsodium和NaCL库;对应libsodium不支持的加密算法,考虑统一底层加密库,同时桌面版对包大小不敏感,可以使用OpenSSL
参考资料
- Apple Cryptographic Libraries: https://developer.apple.com/cryptography/
- javax.crypto: https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/package-summary.html
- 现代密码学实践指南[2015年]:https://blog.helong.info/blog/2015/06/05/modern-crypto/