SHA1 PHP mcrypt_解密结果

SHA1 PHP mcrypt_解密结果,php,encryption,mcrypt,Php,Encryption,Mcrypt,我有两个使用PHP mcrypt库的加密和解密函数 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, $ke

我有两个使用PHP mcrypt库的加密和解密函数

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
为什么不同?我错过了什么

更新:

公认的答案是有用的。对于需要更多信息的人,请参阅:

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

trim()
之后,SHA1结果按预期工作,因为空隐藏的
0
被删除。

问题是解密字符串返回16个字节的字符串,该字符串右侧填充了0个字节。这是个问题

从右侧删除空字节,行与此类似:

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

请注意不要在结尾使用空字符加密内容,因为PHP中的密码学函数的工作方式就像所有字符串都以空结尾一样,并且不羞于首先剪切字符串
\0
,或者返回一点粘在输出末尾的
\0

在后加密数据中+符号将替换为空白。这就是为什么不做解密的原因。

比较<代码> BI2HEX($PASS)< /C>和<代码> BI2HEX($PASSY DECRYPT)。为什么你认为这是一个bug?问题是您选择了有损填充模式(零填充),因此删除它不可能可靠地删除它。加密时应使用可移动填充。@CodesInChaos改为“问题”-这至少是一个问题,因为它在PHP.net上的dosc中没有很好的文档记录。填充参数为,填充返回值为。