使用 crypt() 和 password_hash() 函数加密后密码不匹配
我修改了我的旧帖子.我尝试了 crypt() 函数,现在尝试使用 password_hash() 和 password_verify() 来验证来自数据库的加密密码,但是在每次调用时,password_hash() 函数会重新调整不同的加密字符串,而 password_verify() 无法匹配它.
I modified my old post. I tried the crypt() function and now trying to work with password_hash() and password_verify() to verify the encrypted password coming from database but on each call, password_hash() function retuns a different encrypted string and password_verify() cannot match it.
我就是这样做的.
//please ignore the syntax error if any
$data = '11';
$dbpass = password_hash($data, PASSWORD_BCRYPT);
echo $dbpass; // displays the random strings on each page refresh.
一旦密码被保存到数据库中,在登录过程中不会匹配.下面是我的实际功能.
Once password is saved into database does not get match during the login process. Below is my actual function.
private function process_data($password){
$password = __STR.$password.__STR;
return password_hash($password, PASSWORD_BCRYPT);
}
private function processed($login_password, $dbpassword){
$login_password = __STR.$login_password.__STR;
return password_verify($login_password, $dbpassword);
}
在每次为密码创建哈希字符串的函数调用中,该函数下一次返回不同的字符串.
On each function call for creating a hashed string for password, the function returns the different string next time.
推荐答案
好,我们来一一道来.
首先,它是散列,而不是加密.加密是两种方式,散列是一种方式.我们想要散列.我们从不想加密.是的,术语很重要.请使用正确的术语.
First, it's hashing, not encryption. Encryption is two-way, hashing is one way. We want to hash. We never want to encrypt. Yes, terminology matters. Please use the correct terminology.
接下来,password_hash
的每次调用都假定返回不同的哈希值.那是因为它会生成强随机盐.这就是它的设计方式,以及您真正应该如何使用它.
Next, each call to password_hash
is supposed to return a different hash. That's because it's generating a strong random salt. This is how it was designed, and how you really should be using it.
此外,请勿在密码前后添加 __STR
.除了可能会削弱用户密码之外,您什么也没做(这不好).如果您想了解有关为什么这是一个坏主意的更多信息:阅读此答案.
Further, DO NOT do the "pepper" thing of adding __STR
before and after the password. You're doing nothing but potentially weakening the users password (which is not good). If you want more information around why that's a bad idea: Read This Answer.
继续,我强烈建议您不要直接使用 crypt
.实际上,搞砸并生成极弱的哈希值非常容易.这就是设计 password_*
api 的原因.crypt
是一个低级库,您想在代码中使用高级库.有关如何搞砸 bcrypt 的更多信息,请查看我的博客:搞砸 Bcrypt 的七种方法.
Continuing, I would highly recommend that you do not use crypt
directly. It is actually surprisingly easy to screw up and generate extremely weak hashes. This is why the password_*
api was designed. crypt
is a low level library, you want to use a high level library in your code. For more information on ways to screw up bcrypt, check out my blog: Seven Ways To Screw Up Bcrypt.
Password API 旨在成为一个简单的一站式商店.如果它不适合您,请检查以下事项:
The Password API was designed to be a simple, one-stop shop. If it's not working for you check the following things:
您使用的是 PHP >= 5.5.0 吗?或者您使用 PHP >= 5.3.7 和 password_compat?
您的数据库列是否足够宽?
Is your database column wide enough?
它需要至少 60 个字符.
It needs to be at least 60 characters long.
你是否检查函数的结果是一个字符串,而不是 bool(false)
?
Are you checking that the result of the function is a string, and not bool(false)
?
如果有内部错误,它会从 password_hash
返回一个非字符串.
If there is an internal error, it will return a non-string from password_hash
.
您是否遇到任何错误?
您是否已将 error_reporting
设置为最大设置(我建议 -1
捕获所有内容)并检查代码没有抛出任何错误?
Have you turned on error_reporting
to its maximum setting (I recommend -1
to catch everything) and checked that the code isn't throwing any errors?
你确定你使用正确吗?
function saveUser($username, $password) {
$hash = password_hash($password, PASSWORD_BCRYPT);
// save $username and $hash to db
}
function login($username, $password) {
// fetch $hash from db
return password_verify($password, $hash);
}
请注意,每个都只能调用一次.
Note that each one should be called only once.
你在用PHP吗<5.3.7 使用 password_compat?如果是这样,这是你的问题.您在不受支持的 PHP 版本上使用兼容性库.您可能会让它工作(某些 RedHat 发行版已经向后移植了必要的修复程序),但您使用的是不受支持的版本.请升级到合理的版本.
Are you using PHP < 5.3.7 with password_compat? If so, this is your problem. You are using the compatability library on an unsupported version of PHP. You may get it to work (certain RedHat distributions have backported the necessary fixes), but you are using an unsupported version. Please upgrade to a reasonable release.
如果一切都失败了,请尝试运行此代码并报告输出:
If all else fails, please try running this code and reporting back the output:
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;
echo "Test for functionality of compat library: " . ($pass ? "Pass" : "Fail");
echo "
";
如果返回 Fail
,则您运行的是不受支持的 PHP 版本,应该升级.如果它返回通过,那么错误就在您的逻辑中(库运行正常).
If that returns Fail
, you are running an unsupported version of PHP and should upgrade. If it returns pass, than the error is somewhere in your logic (the library is functioning fine).
相关文章