我修改了我以前的帖子。我尝试了crypt()函数,现在尝试使用password_hash()和password_verify()来验证来自数据库的加密密码,但是在每次调用时,password_hash()函数都会返回一个不同的加密字符串,而password_verify()无法匹配它。
这就是我所做的。
//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.一旦密码被保存到数据库中,在登录过程中不匹配。下面是我的实际函数。
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);
}在每次调用为password创建散列字符串的函数时,该函数下次都会返回不同的字符串。
发布于 2013-10-31 22:17:49
好的,让我们一个接一个地看一遍。
首先,它是散列,而不是加密。加密是双向的,散列是单向的。我们想要散列。我们从来不想加密。是的,术语很重要。请使用正确的术语。
接下来,每次对password_hash的调用都被假定为,以返回不同的散列。这是因为它产生了一种很强的随机盐。这就是它是如何设计的,以及你应该如何使用它。
此外,不会像“”那样在密码前后添加__STR。您什么也不做,只是潜在地削弱了用户密码(这是不好的)。如果你想了解更多关于为什么这不是个好主意的信息,请访问Read This Answer。
继续,我强烈建议您不要直接使用crypt。实际上,很容易搞砸并生成极弱的散列。这就是设计password_*应用程序接口的原因。crypt是一个低级库,您希望在代码中使用高级库。有关搞砸bcrypt的更多信息,请查看我的博客:Seven Ways To Screw Up Bcrypt。
Password API被设计成一个简单的一站式商店。如果它对你不起作用,请检查以下内容:
的PHP >= 5.3.7
1. Is your database column wide enough?它需要至少为 60个字符的长度。
2.是否检查函数的结果是字符串,而不是bool(false)?
如果存在内部错误,它将从password_hash返回一个非字符串。
3.你收到什么错误了吗?
您是否将error_reporting设置为最大值(我建议使用-1来捕获所有内容),并检查代码是否没有抛出任何错误?
4.确定使用正确吗?
函数saveUser( $username,$password) { $hash = password_hash($password,PASSWORD_BCRYPT);//将$username和$hash保存到数据库}函数登录($username,$password) { //从数据库获取$hash返回password_verify($password,$hash);}
请注意,每个函数应该只调用一次。
如果所有其他方法都失败了,请尝试运行此代码并报告输出:
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;
echo "Test for functionality of compat library: " . ($pass ? "Pass" : "Fail");
echo "\n";如果返回Fail,则说明您正在运行不受支持的PHP版本,应进行升级。如果它返回pass,那么错误就在您的逻辑中的某个地方(库运行正常)。
发布于 2013-10-30 20:16:07
存储密码的最好方法是使用PHP的函数password_hash()。它会自动为每个密码生成加密安全的salt,并将其包含在生成的60个字符的字符串中。你根本不用担心盐的问题!
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);你自己的方案非常弱,首先你使用MD5生成密码散列太快,然后你使用静态盐,这违背了盐的目的。也许你想看看我关于safely storing passwords的教程。
编辑以回答更新的问题:
没有必要将__STR添加到密码中(如果您想添加胡椒,还有更好的方法),但您的示例函数实际上应该可以工作。由于随机盐的存在,password_hash()的返回值每次都会不同。这是正确的,函数password_verify()能够提取此盐进行验证。在您的例子中,数据库字段可能是问题所在。确保它可以容纳60个字符的字符串。
https://stackoverflow.com/questions/19662767
复制相似问题