使用PHP 5.5的password_hash和password_verify功能使用PHP 5.5

2019-05-06 04:14发布

说我想存储密码用户,这会不会与PHP 5.5的做正确的方式password_hash()函数(或该版本的PHP 5.3.7+: https://github.com/ircmaxell/ password_compat )?

$options = array("cost" => 10, "salt" => uniqid());
$hash = password_hash($password, PASSWORD_BCRYPT, $options);

然后,我会做:

mysql_query("INSERT INTO users(username,password, salt) VALUES($username, $hash, " . $options['salt']);

插入到数据库中。

然后验证:

$row = mysql_fetch_assoc(mysql_query("SELECT salt FROM users WHERE id=$userid"));
$salt = $row["salt"];
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10, "salt" => $salt));

if (password_verify($password, $hash) {
    // Verified
}

Answer 1:

忽略与您的数据库语句的问题,现在,我会回答有关问题password_hash

总之,不,这不是你怎么做。 你不想单独存储盐,你应该都存储在哈希和盐,然后同时使用来验证密码。 password_hash返回包含两者的字符串。

password_hash函数返回一个包含两个哈希和盐的字符串。 所以:

$hashAndSalt = password_hash($password, PASSWORD_BCRYPT);
// Insert $hashAndSalt into database against user

然后验证:

// Fetch hash+salt from database, place in $hashAndSalt variable
// and then to verify $password:
if (password_verify($password, $hashAndSalt)) {
   // Verified
}

此外,作为意见建议,如果你有兴趣在安全性,你可能想看看mysqliext/mysql在PHP5.5不建议使用),并且也是本文的SQL注入: http://php.net/manual /en/security.database.sql-injection.php



Answer 2:

使用你自己的盐是不建议,因为PHP 7的, 它的使用已被弃用 。 要理解为什么,笔者password_hash共享这些想法(链接已不存在)

有一件事情变得非常清楚对我说:盐的选择是很危险的。 我还没有看到,已经连像样的盐选项的单次使用。 从坏的(通过mt_rand()输出)到危险的(静态字符串),以疯狂的每次使用范围(通过密码作为自己的盐)。

我来,我不认为我们应该允许用户指定盐的结论。

他甚至提出在SO此评论聊天指出多么糟糕传递自己的盐可



Answer 3:

请注意,这从php.net

警告

盐选项已被弃用的PHP 7.0.0的。 现在优选的是简单地使用由默认生成的盐。

结论? 忘了盐的选择。

这将是完全够用password_hash('password', PASSWORD_DEFAULT) *(或_BCRYPT)



Answer 4:

你不应该进入自己的盐,盐留下空,函数将产生良好的随机盐。

插入到数据库(或文件或任何你使用)全由该函数返回的字符串。 它包含:算法,成本,盐(22个字符)和散列密码的ID。

整个字符串需要使用password_verify()。 盐是随机的,不会伤害到落入坏人之手(与哈希密码)。 这可以防止(或很困难)使用准备集合生成的密码和哈希的列表 - 彩虹表。

你应该考虑增加成本参数。 缺省(如果省略) 为10 -如果高于函数计算散列更长。 通过1增加了成本,双所需的时间以生成散列(并因此延长它需要打破密码的时间)

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));

你应该根据你的服务器上的速度检查设置此参数。 建议功能进行100毫秒+(有些人喜欢让250毫秒)。 一般成本= 10或11是一个很好的选择(在2015)。

为了提高安全性,您可能要添加到口令长(50-60个字符是不错的选择)秘密字符串。 您使用password_hash()或password_verify前()。

$secret_string = 'asCaahC72D2bywdu@#$@#$234';
$password  = trim($_POST['user_password']) . $secret_string;
// here use password_* function

小心操作使用PASSWORD_BCRYPT为ALGO参数,将导致在密码参数被截断到72个字符的最大长度。

如果$密码将长于72个字符,并且您更改或添加73或90个字符乱码不会改变。 可选,坚持$ secret_string应该是在年底(该用户的密码,而不是之前之后)。



文章来源: Using PHP 5.5's password_hash and password_verify function