【问题标题】:SHA1 the PHP mcrypt_decrypt resultSHA1 PHP mcrypt_decrypt 结果
【发布时间】:2013-10-23 04:16:10
【问题描述】:

我有 2 个使用 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

【问题讨论】:

  • 比较bin2hex($pass)bin2hex($pass_decrypt)

标签: php encryption mcrypt


【解决方案1】:

问题是您的 decrypt_string 返回 16 字节字符串,右侧填充 0 字节。这是一个问题known for about 2 years

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

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

注意不要在末尾用空字符加密东西,因为 PHP 中的密码学函数就像所有字符串都以空结尾一样工作,并且一开始就不会害羞\0 或返回一点@987654324 @s 粘在他们输出的末尾。

【讨论】:

  • 你为什么认为这是一个错误?问题是您选择了有损填充模式(零填充),因此无法可靠地删除它。加密时应使用可移动填充。
  • @CodesInChaos 更改为“问题” - 这至少是一个问题,因为它在 PHP.net 的 dosc 中没有很好地记录。填充参数是,填充返回值不是。
【解决方案2】:

在加密后的数据中 + 符号将被替换为空格。这就是为什么没有完成解密的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2018-04-25
    • 1970-01-01
    • 2017-09-18
    • 2011-11-28
    • 2021-06-06
    • 2015-09-15
    相关资源
    最近更新 更多