2013-10-15 44 views
3

我有2加密&使用PHP mcrypt庫解密函數。SHA1 PHP mcrypt_decrypt結果

public function encrypt_string($input, $key) { 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv); 
    return base64_encode($iv . $cipher); 
} 
public function decrypt_string($input, $key) { 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
    $ciphertext = base64_decode($input); 
    $iv = substr($ciphertext, 0, $iv_size); 
    $cipher = substr($ciphertext, $iv_size); 
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv); 
} 

鑑於該密鑰是由產生:

$key = pack('H*', 'dfgsdighsdfksdhfosdfasdjldsfsdfgdfkgdl'); // a random key 

我可以成功獲得回加密解密&之後的輸入。

下面是代碼:

$pass = '123456'; 
echo sha1($pass) . PHP_EOL; // prints 7c4a8d09ca3762af61e59520943dc26494f8941b 
$pass_cipher = encrypt_string($pass, $key); 
$pass_decrypt = decrypt_string($pass_cipher, $key); 
echo $pass_decrypt . PHP_EOL; // prints 123456 
echo sha1($pass_decrypt) . PHP_EOL; // prints f41b44dbecccaccfbb4ccf6a7fc4921c03878c6d 

然而,SHA1結果不同的是:

7c4a8d09ca3762af61e59520943dc26494f8941b // before encrypt & decrypt 
f41b44dbecccaccfbb4ccf6a7fc4921c03878c6d // after encrypt & decrypt 

它爲什麼不一樣?我錯過了什麼 ?

UPDATE:

接受的答案是非常有用的。對於誰想要更多的信息的人,在這裏它是:

trim()
echo bin2hex($pass) . PHP_EOL; // prints 313233343536 
echo bin2hex($pass_decrypt) . PHP_EOL; // prints 31323334353600000000000000000000 

,並在SHA1結果正常工作,如空隱藏0被刪除。

+2

比較'bin2hex($ pass)'和'bin2hex($ pass_decrypt)'。 – deceze

回答

6

問題是您的decrypt_string返回16字節的字符串,在右側填充0字節。這是一個問題known for about 2 years。要小心,不要在最後用空字符加密的東西,如PHP密碼學功能的工作原理就好像所有的字符串是空值

return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv), "\0"); 

:從行權類似於此

刪除空字節終止,並不害羞地開始削減字符串\0或返回一點點\0 s粘在他們的輸出結束。

+0

你爲什麼認爲這個bug?問題是你選擇了有損填充模式(零填充),所以刪除它不可能可靠地刪除它。加密時應使用可移動的填充。 – CodesInChaos

+1

@CodesInChaos更改爲「問題」 - 這至少是一個問題,因爲它在PHP.net上的dosc中沒有很好記錄。填充參數是,填充返回值不是。 –

0

在後加密數據+符號將被替換爲空格。這就是爲什麼解密沒有完成。