對帶有 OAEP 填充的 RSA 使用 SHA1 而不是 SHA256 的風險
我目前正在 PHP 中實現一個簡單的基於 RSA 的加密,如下所示(使用 openssl_public_encrypt):
// $sRawText is the text string to encrypt. // $sPublicKey is the public key stored on the server. openssl_public_encrypt($sRawText, $sResult, $sPublicKey, OPENSSL_PKCS1_OAEP_PADDING); // $sResult is the encrypted result which is then stored.
我確保使用 OAEP 填充選項,但是填充是使用 SHA1 而不是 SHA256 完成的。PHP 沒有支持 SHA256 的內置填充選項。例如,Python 的密碼庫使用 SHA256,如下所示:
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding ciphertext = public_key.encrypt( message, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) )
我在 PHP 上獲得 SHA256 的唯一選擇是使用第三方庫,如 PHPSecLib 或 EasyRSA。在嘗試在我的共享託管環境中安裝和使用其中任何一個小時後,我遇到了障礙。(如果我可以將一個包含 RSA 的 .php 文件放在一個地方,那將是理想的。)
數據被加密到線上伺服器上的數據庫中,這必須在 PHP 中進行,因此我可以在使用者註冊時插入新條目(使用公鑰)。我想確保如果加密的數據庫數據和公鑰落入具有合理計算能力的邪惡之手,數據將保持私密(與暴力攻擊一樣安全)。不法分子手中的數據可能會被濫用來釣魚使用者或製造欺詐性虛假聲明。
客戶端儲存不起作用,因為數據目前已經在數據庫中,我需要某些欄位,例如聯繫資訊,以便聯繫使用者。另外,我覺得大多數客戶會失去數據,這些數據是不可恢復的,並且可能需要幾年後仍然可用。但是,我不希望完全信任伺服器環境,因此我希望將攻擊面最小化到僅在使用數據的特定時刻。對我來說,讓私鑰和密碼片語保持離線和安全比嘗試保護不斷變化且需要冗餘儲存的動態數據庫要容易得多。
我計劃離線對加密數據進行所有操作,並且只使用加密的數據庫欄位進行驗證(即數據與使用者輸入的內容匹配)或計算條目。數據庫中的某些欄位不敏感,因此未加密,而其他欄位(例如密碼)則經過雜湊處理。
我想知道的是,如果我繼續執行 SHA1 填充實現,這將使我面臨什麼樣的攻擊,以對抗具有加密數據庫數據和公鑰的對手。他們將如何應對這些攻擊?SHA256 填充是否有助於更好地保護數據,以及如何?
非常感謝!
您可以將 SHA-1 或 MD5 用於 OAEP。它不會讓你受到任何攻擊。
OAEP 將散列函式用於兩件事:對標籤進行散列處理,以及作為遮罩生成函式的一部分,在實踐中,遮罩生成函式始終是某個散列函式的 MGF1。
對於標籤,雜湊函式只是用來將標籤變成密文域分隔符:解密時,將標籤雜湊錯誤的密文檢測為無效。只要您不使用可以由對手提供的元件來建構標籤,您就不會冒碰撞的風險。而且,如果您確實以復雜的方式建構標籤並且您依賴它來確保安全,那麼您可能無論如何都應該有一個簽名。
對於 MGF1,散列函式用作隨機預言機。它作為散列的屬性是不相關的。已棄用的以前流行的散列函式已被棄用,因為它們作為散列函式的屬性(特別是抗碰撞性)受到了具體的攻擊。但是,作為隨機預言機,它們仍然被認為與以往一樣好。(它們有一個已知的缺陷,即長度擴展,也適用於 SHA2,它沒有作為散列函式的已知缺陷。但是長度擴展無論如何都不適用於 OAEP 中的 MGF1,因為它用於固定大小的輸入給定的 RSA 密鑰。)
在加密結構中使用 SHA-1 可能會使審計人員皺眉,並且會使您的系統不符合某些安全標準。在安全性方面,這有點讓人分心,但不是漏洞。