我想改進某個使用現已過時的「mcrypt」的 WordPress 外掛。相反,我想使用OpenSSL 庫來加密提交的數據,但在加密過程中我遇到了問題,即: openssl_encrypt 函數返回與mcrypt_encrypt 不同的值,我連接到的系統不會返回我的值正確的數據,並且其所有者無法向我發送我上傳到其中的內容的日誌:(
我已經搜尋了整個互聯網,但還沒有找到解決方案。我懷疑問題出在填充物上,但我找不到解決方案。你能幫忙嗎?
下面是我的 PHP 物件 $password、$salt 和 $iv 的內部明顯發生了變化
class EncryptDebug{ private $algo = 'sha1'; private $password = 'ab4232goodcf423484422c90c3e4aa7c'; private $salt = 'ascastas54490a31'; private $iv = '8947da32awl55kwj' private $lenght = 16; private function generate_key(){ return hash_pbkdf2( $this->algo , $this->password , $this->salt, 100, $this->lenght, true ); } public function encryptSSL($plaintext){ $key = $this->generate_key(); $ciphertext = base64_encode(openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_ZERO_PADDING, $this->iv)); return str_replace('+', '%2B', $ciphertext); } public function encryptMCRYPT($plaintext){ $key = $this->generate_key(); $ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $this->iv)); return str_replace('+', '%2B', $ciphertext); } }
忘記提及:OPENSSL_ZERO_PADDING 回傳錯誤。使用 OPENSSL_RAW_DATA 我可以獲得與 mcrypt_encrypt 類似的結果,但結局不同,例如:
OpenSSL:rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG+VPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8WcNzMJ868026TkUxcYJMrQ==
MCRYPT:rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG+VPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8UGVfF091Q9bY61mTRg+BSg==
在
encryptSSL()
中,目前使用 Base64 編碼兩次,預設一次是明確編碼,一次是隱式編碼。因此,必須刪除其中一種 Base64 編碼,無論是明確編碼還是隱式編碼。前者是透過刪除base64_encode()
呼叫來實現的,後者是透過設定OPENSSL_RAW_DATA
標誌來實現的。此外,mcrypt 使用零填充,PHP/OpenSSL 使用 PKCS#7 填充。因此,為了使
encryptSSL()
給出與encryptMCRYPT()
相同的結果,必須使用零填充。由於 PHP/OpenSSL 不支援零填充,因此必須停用 PKCS#7 填充(使用 OPENSSL_ZERO_PADDING 標誌)並且必須明確實現零填充>.總體:
與:
透過這些更改,兩個函數給出相同的結果。
請注意,與 PKCS#7 填充相比,零填充不可靠。
安全性:
請注意,靜態 IV 和靜態鹽是漏洞。相反,兩者都將隨機生成並與密文一起傳遞到解密方,通常是串聯的(兩者都不是秘密的)。
此外,PBKDF2 的迭代次數為 100 通常太小。