我一直使用您的網站來幫助我解決各種編程問題,並且終於遇到了一個我在其他地方找不到的問題。使用MCRYPT加密/解密PHP ...結果不一致
我試圖在PHP中使用mcrypt來加密和解密存儲在我客戶網站上的密碼。這些密碼用於外部網站,因此它們必須經過加密/解密而不是散列。我目前正在將其舊框架Legato更新爲更新的Yii框架。密碼使用類文件中列出的加密方案存儲在當前數據庫中。該方案如下:
<?php
//--------------------------------------------------------------------------
// Name: Legato_Encryption
// Desc: An encryption engine. Contains functions to encrypt and decrypt
// text.
//--------------------------------------------------------------------------
class Legato_Encryption
{
//------------------------------------------------------------------------
// Public Variables
//------------------------------------------------------------------------
private $_cypher; // The cypher algorithm.
private $_mode; // The encryption mode.
private $_td; // The TD for mcrypt.
private $_private_key; // The private key.
//------------------------------------------------------------------------
// Public Member Functions
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Name: __construct()
// Desc: Class constructor.
//------------------------------------------------------------------------
public function __construct($private_key, $cypher = 'blowfish', $mode = 'cfb')
{
// Make sure everything was filled in.
if ($private_key == "" || $cypher == "" || $mode == "")
{
Legato_Debug_Debugger::add_item('Invalid parameters for encryption. NULL passed in.');
return false;
}
// Assign the class variables to those passed in.
$this->_cypher = $cypher;
$this->_mode = $mode;
// Get the TD.
$this->_td = mcrypt_module_open($this->_cypher, '', $this->_mode, '');
// Get the expected key size based on mode and cipher .
$expected_key_size = mcrypt_enc_get_key_size($this->_td);
// We dont need to know the real key, we just need to be able to confirm a hashed version.
$this->_private_key = substr(md5($private_key), 0, $expected_key_size);
}
//------------------------------------------------------------------------
// Name: encrypt()
// Desc: Encrypts the plaint text passed in.
//------------------------------------------------------------------------
public function encrypt($plaintext)
{
// Create the IV.
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->_td), MCRYPT_RAND);
// Initialize the mcrypt engine.
mcrypt_generic_init($this->_td, $this->_private_key, $iv);
// Encode/encrypt the text.
$crypttext = base64_encode(mcrypt_generic($this->_td, $plaintext));
// Shut down mcrypt.
mcrypt_generic_deinit($this->_td);
// Return the iv prefixed to the encrypted text.
return $iv . $crypttext;
}
//------------------------------------------------------------------------
// Name: decrypt()
// Desc: Decrypts the encrypted text passed in.
//------------------------------------------------------------------------
public function decrypt($crypttext)
{
// Get the iv from the beginning of the encrypted text.
$iv_size = mcrypt_enc_get_iv_size($this->_td);
$iv = substr($crypttext, 0, $iv_size);
// Get the encrypted text.
$crypttext = substr($crypttext, $iv_size);
$plaintext = '';
// Attempt to decrypt the text.
if ($iv)
{
// Initialize the mcrypt engine.
mcrypt_generic_init($this->_td, $this->_private_key, $iv);
// Decode the crypted text, then decrypt it, then trim it of whitespaces.
$plaintext = trim(mdecrypt_generic($this->_td, base64_decode($crypttext)));
// Shut down mcrypt.
mcrypt_generic_deinit($this->_td);
} // End if $iv true.
// Return the plain text.
return $plaintext;
}
}
我的問題是,使用實時服務器上的類,它準確地進行加密和解密的密碼。如果我把這段代碼粘貼到一個新文件中,並以相同的輸入方式使用它,它會返回一個不同的字符串,通常使用「?」字符(不是問號字符,而是Web瀏覽器無法解釋的字符)。例如,Legato_Encryption('hello','twofish')。encrypt('hello')將返回與Yii_Encryption('hello','twofish')中使用它完全不同的東西。encrypt('你好')。這是相同的代碼和相同的過程與相同的參數...它怎麼能返回不同的值?我相信encrypt()函數似乎在每次執行時都會生成隨機值,但decrypt()應該返回正確的字符串。
有沒有人看到一個可能的區域,在這個代碼可能是脾氣暴躁或產生不一致的結果?我在這個問題上花費了太多時間,因爲許多其他關於類似問題的帖子都沒有取得成功。
也許相關:http://stackoverflow.com/questions/2283937/how -hould-I-ethically-approach-user-password-storage-for-later-plaintext-retrieve – ntoskrnl
另請參閱Openwall的[便攜式PHP密碼哈希框架](http://www.openwall.com/phpass/)。它強化了對用戶密碼的一些常見攻擊。 – jww