若是本文中的術語讓你感到疑惑,請先參閱密碼學術語及概念一文。php
密碼學不是魔術。加密一個應用程序並不能保證它在襲擊下的安全(特別是在你沒有設置驗證密文的狀況下)。但若是出於商業需求你要確保程序的安全,傳統作法會建議你最好不要嘗試設計你本身的密碼。你應該使用已有的密碼庫。html
好了,以上我都瞭解了。那麼我應該用哪一個PHP密碼庫呢?git
這取決於你的實際需求。讓咱們來看一下一些好的選擇。(咱們不會說起任何糟糕的密碼庫的。)github
##安全的PHP密碼庫建議算法
下面是一個安全信任度較高的可部署在生產環境中的PHP密碼庫清單。本清單基於如下三項標準進行優先排序。數據庫
###Halite – 來自 Paragon Initiative Enterprises編程
咱們推薦此密碼庫不只是由於它是咱們自寫的,首推它是由於你能夠經過簡單直觀的接口獲取使用libsodium的所有安全保護。這是一款免費軟件,而且源碼是能夠直接獲取的。安全
####使用Halite的好處服務器
• 主線cookie
• 全文件加密(見:全部主線特徵)
• 加密cookies
• 密碼存儲
• 你不須要知道現時值是什麼,你也不須要特別關注認證加密。Halite會幫你作好一切。
咱們建立Halite以供PHP開發者經過一個更簡單的接口獲取libsodium拓展的全部安全性優點。查看Halite的相關文件就能知道它的使用是多麼簡便。(儘管 API 是固定的,Halite幫助文件依然是不完善的。然而它已經足以涵蓋入門級的內容。)
惟一的缺陷是你必須安裝PHP的libsodium擴展包才能使用Halite。所以對於不少項目來講,Halite方式是行不通的。
####安裝指南:
很顯然,若是你不喜歡咱們對於Halite所作的決策,那麼能夠考慮直接使用libsodium。
####使用libsodium的優點
• 對稱密鑰加密認證(同:AEAD)
• 對稱密鑰認證
• 非對稱密鑰認證加密
• 非對稱密鑰匿名加密
• 非對稱密鑰數字簽名
• 加密哈希函數
• 密碼存儲
• 瑞士軍刀式的密碼學原語(好比:基於Curve25519的Diffe-Hellman密鑰交換協議的橢圓曲線)
• 在PHP中的內存清除(補零)能力
• 還有好多
請向Frank Denis以及創做了NaCl(libsodium由此分生)的小組致敬,由於libsodium一直是世界上最可靠的,跨平臺的密碼學庫。
####安裝指南
請參閱相關文件。
###PHP Encryption – 來自 Defuse Security
若是你不能從PECL(也就是永遠不能安裝libsodium)安裝PHP拓展包,這個密碼庫應該是你的備用選擇。一般狀況下,不論你的框架提供了什麼方案,你都應該優先考慮它,由於咱們的安全小組常常能發現PHP框架提供的對稱密鑰加密功能的缺陷。
####使用Defuse Security 的 PHP密碼庫的優點:
• Symmetric-key authenticated encryption
• 對稱密鑰認證加密
它解決了大多數人都會遇到的一個問題(而且解決得很是棒)。該密碼庫的第二版(即將發佈!)將一樣涵蓋全文件加密,可是因爲它還未發佈,所以咱們還不能以此爲加分項。
####Phpseclib - Jim Wigginton, et al. (僅對 RSA 而言)
若是你必定要安裝對稱密鑰加密,請使用上述的Defuse的密碼庫。Defuse Security的密碼庫爲你提供了認證加密,而phpseclib的AES實施並不會驗證密文。所以若是你使用它,你對選擇密文攻擊的抵抗力將十分脆弱。(他們的交互文件在ECB模式下一樣出錯嚴重,是咱們提過的最壞分組密碼模式。)
儘管phpseclib爲通用對稱祕鑰加密方式提供的 API 等級太低,使得咱們不肯向缺少密碼學背景的PHP開發者在這種使用方式下推薦它,可是它相對extopenssl而言提供了一種更好的非對稱祕鑰加密方式。
若是你堅持必須使用非對稱祕鑰加密方式(公共祕鑰加密,電子簽名)而且出於各類緣由沒法使用libsodium,那麼你就應該考慮安裝phpseclib,而且嚴格遵循Colin Percival提出的密碼算法的正確解答。
####特別注意
若是你恰好是一位密碼學專家,那你能夠忽略咱們的警示信息,使用phpseclib提供的對稱祕鑰加密方式。可是對大多數非密碼學專家的編程者來講,請最好不要忽略咱們的提示。
####使用PHPSecLib的優點:
###更新內容 (2015-11-19) Easy RSA 在本篇博客發佈之後,咱們又針對建議開發了插入式安裝包,EasyRSA。EasyRSA是一種方向肯定且默認安全設置的phpseclib使用。
####EasyRSA加密過程
問題:使用RSA加密一段超大字符串,即便RSA自己也不支持加密超大字符串數據。
原始解決方案是將你輸入的字符串切分分塊並單獨分別加密。然而這和可怕的電碼本(ECB)模式十分類似。一樣的:它的處理進程也十分緩慢。這是個很是糟糕的解決方案。
####咱們的解決方案
生成臨時祕鑰
使用Defuse Security的PHP對稱祕鑰加密密碼庫加密您的消息
使用已有RSA公共祕鑰加密臨時祕鑰(一種對padding oracles攻擊方式抵抗效果良好的方式)
基於64位編碼,而且使用版本標記前綴來鏈接密文
附加第四步中的校驗和(截取的哈希SHA256加密算法)來加強傳輸存儲錯誤檢測能力。
####要解密一段消息
EasyRSA只使用RSAES-OAEP + MGF1-SHA256 with e = 65537來進行公鑰加密,已知此種加密方式對任何padding oracle攻擊都是有良好抵抗力的。
####EasyRSA 簽名方式
RSA簽名方式是相對直接的:使用RSASS-PSS + MGF1-SHA256 with e = 65537來計算RSA簽名,而後校驗它是否設定爲僅接受此種簽名。
可是認真講,若是你真的想爲你的PHP程序找到一種確保安全的加密方式,請嘗試尋找能使用libsodium的方式。咱們正推進使libsodium成爲PHP7.1中的核心拓展包,所以但願它的使用可以在未來同「更新新版PHP」同樣簡單。
##關於咱們提供的PHP加密庫建議
###那其餘密碼庫呢?
任何未在上文說起的密碼庫的落選緣由均可以由如下三條可能緣由解釋:
若是你對咱們認定有缺陷的密碼庫感興趣,請查看安全建議頁以獲取更多信息。
###在PHP中,咱們應該使用何種方式加密密碼?
你不須要加密密碼,你只須要用合適的密碼散列算法(哈希密碼算法)來雜亂密碼。當前的最佳密碼庫之一是PHP內建的: password_hash() andpassword_verify()。這種散列算法對99%的編程者或企業來講都是穩定有效的。這個算法就是這麼棒。
然而,若是你將數據庫中的密碼存儲在你網頁應用的不一樣服務器中,你能夠經過加密散列(而不是加密密碼自己)來減輕密碼入侵風險。要使用這種方式,請查看Halite密碼課程。
##重要的安全建議免責聲明
儘管咱們僱傭了一些PHP開發安全的行業頂尖專家(而且咱們精於應用密碼學),在不瞭解你的特定項目要求和風險模型的前提下,他們在寫做這篇嚮導時並不能指引你選取最符合需求的解決方案。
所以若是,好比,你須要使用非對稱加密算法,還執意選擇使用Defuse Security的對稱加密密碼庫,請不要說「是Paragon Initiative Enterprises讓我這麼幹的!」
若是你想根據本身的特定項目得到咱們的安全建議,請考慮僱用咱們進行安全諮詢服務。
或者用法律術語說:此文信息不提供任何擔保,使用風險自負。
原文地址:Choosing the Right Cryptography Library for your PHP Project: A Guide
本文系 OneAPM 工程師編譯整理。OneAPM 是應用性能管理領域的新興領軍企業,能幫助企業用戶和開發者輕鬆實現:緩慢的程序代碼和 SQL 語句的實時抓取。想閱讀更多技術文章,請訪問 OneAPM 官方博客。 本文轉自 OneAPM 官方博客