我今天正在玩Blowfish算法。一切正常,但有时我的程序失败,因为Blowfish Algo将*0
作为输出,所以整个逻辑在之后就会崩溃。
在CRYPT
下的changelog
的PHP官方文档页面上,提到此问题已在5.3.2版本中解决
5.3.2 Fixed Blowfish behaviour on invalid rounds to return "failure" string ("*0" or "*1"), instead of falling back to DES.
我正在使用PHP 5.5.9-1ubuntu4.2
并仍面临同样的问题。这是程序:
<?php
$password = 'Rajat';
$userpassword = 'Rajat';
echo $password;
echo "\n";
echo "Salt: ";
$salt = substr(uniqid(rand()),0,22);
echo $salt;
echo "\n";
echo "Using Blowfish: ";
$bf = crypt($password,'$2y$10$'.$salt);
echo $bf;
echo "\n";
echo "Starting password checking...\n";
$full_bf_salt = substr($bf,0,29);
$verify_hash = crypt($userpassword,$full_bf_salt);
echo "Verified calculated hash: ".$verify_hash;
if($verify_hash==$bf){
echo "Password is correct\n";
}else{
echo "Password is incorrect\n";
}
?>
大多数情况下,crypt函数按预期工作,但有时会失败。有人知道为什么或者有什么我以错误的方式实现了吗?
答案 0 :(得分:1)
我设法用你的代码重现错误。当生成的盐的长度小于22时,你得到*0
。在我的例子中,长度是21个字符。
Salt: string(21) "6948531853de8c4cd7a85"
Using Blowfish: *0
Bcrypt期望以base64格式编码的128位salt,导致22个字符的salt。当salt无效时,将返回*0
以指示存在错误。
以下是使用mcrypt_create_iv()
正确生成salt的一种方法:
$raw_salt_len = 16;
$required_salt_len = 22;
$salt = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
$base64_digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$bcrypt64_digits = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$base64_string = base64_encode($salt);
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
if (function_exists('mb_substr')) {
$salt = mb_substr($salt, 0, $required_salt_len, '8bit');
} else {
$salt = substr($salt, 0, $required_salt_len);
}
我从password_compat库中提取了此代码。我强烈建议研究它的代码。它涵盖mcrypt_create_iv()
不可用时的案例等。