如何安全使用加密套件?

zealotke發表於2018-04-27

如何安全使用加密套件?

對稱加密

  1. 首選 Chacha20-Poly1305 和 AES-GCM 演算法(AEAD類演算法)
  2. 不支援 AES-GCM 或 Chacha20-Poly1305 的場景下使用 AES-CBC,避免 ECB、CTR、CFB、OBF 模式
  3. 避免64bit塊加密演算法,例如 blowfish、TEA 等
  4. 不要使用RC4
  5. 不要自行設計加密演算法,除非你在密碼學領域是整個行業公認的專家
  6. 不要多次迴圈加密,加密強度取決於加密演算法、祕鑰長度,以及正確的實現加密過程。迴圈加密對加密強度沒有實際意義的幫助

原因

  1. Chacha20-Poly1305,AEAD類演算法;繞開了目前所有已知的漏洞;面向移動網際網路優化;ARM架構上效能更佳
  2. AES-GCM,AEAD類演算法;TLS 1.3 draft主要的演算法;工業標準;現代CPU有AES-GCM的硬體指令

對稱祕鑰長度

  1. 對稱祕鑰長度不能低於128 bit,也即16位元組
  2. 長度超過256 bit的對稱祕鑰沒有實際意義
  3. 對稱加密、RSA、ECC三種不同型別的演算法中,同樣的祕鑰長度安全性也不同,下面表格中列出來同樣強度情況下,對應不同演算法的祕鑰長度
  4. 對稱祕鑰生成規則參考本文的 “隨機數生成規範”
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

  1. iv必須隨機生成,不能固定;生成規則參考本文的 “隨機數生成規範”
  2. 避免用祕鑰代替iv
  3. 避免用 stdlib 系列偽隨機數

隨機數生成規範

隨機生成的iv或者nonce要採用/dev/urandom生成,或者採用基於/dev/urandom實現的隨機數生成器

  • 避免採用 stdlib 系列偽隨機數
  • 避免 havaged,prngs,egd 等
  • 避免 /dev/random ,會因為熵池噪聲資料不足而阻塞幾秒甚至是十幾秒,嚴重影響效能,參考:https://zh.wikipedia.org/zh-cn//dev/random

成熟的Library推薦

  1. iOS 可以採用 Randomization Services Reference:https://developer.apple.com/library/ios/documentation/Security/Reference/RandomizationReference/
  2. Android & 服務端Java可以使用 SecureRandom:https://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html
  3. 其他場景:推薦使用libsodium庫,或NaCL庫封裝,或者直接讀取 /dev/urandom

非對稱加密

建議橢圓曲線,避免RSA

主要考慮前向安全性、橢圓曲線效能,以及現代計算機對RSA攻擊能力逐年提升

HMAC演算法

使用SHA2類的演算法:SHA-256,SHA-384,SHA-512,SHA512/256等

避免 SHA-1、MD5、MD6

加密庫選擇

  1. iOS:建議使用原生的 Common Crypto,來自 Apple 的建議:https://developer.apple.com/cryptography/ ;避免使用 OpenSSL,原因是 OpenSSL 介面不友好、漏洞頻發、版本升級時向下相容性不好
  2. Android:建議使用 javax.crypto,https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/package-summary.html
  3. PC & Mac: 優先使用libsodium和NaCL庫;對應libsodium不支援的加密演算法,考慮統一底層加密庫,同時桌面版對包大小不敏感,可以使用OpenSSL

參考資料

  1. Apple Cryptographic Libraries: https://developer.apple.com/cryptography/
  2. javax.crypto: https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/package-summary.html
  3. 現代密碼學實踐指南[2015年]:https://blog.helong.info/blog/2015/06/05/modern-crypto/


相關文章