说我想存储密码用户,这会不会与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
}
忽略与您的数据库语句的问题,现在,我会回答有关问题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
}
此外,作为意见建议,如果你有兴趣在安全性,你可能想看看mysqli
( ext/mysql
在PHP5.5不建议使用),并且也是本文的SQL注入: http://php.net/manual /en/security.database.sql-injection.php
使用你自己的盐是不建议,因为PHP 7的, 它的使用已被弃用 。 要理解为什么,笔者password_hash
共享这些想法(链接已不存在)
有一件事情变得非常清楚对我说:盐的选择是很危险的。 我还没有看到,已经连像样的盐选项的单次使用。 从坏的(通过mt_rand()输出)到危险的(静态字符串),以疯狂的每次使用范围(通过密码作为自己的盐)。
我来,我不认为我们应该允许用户指定盐的结论。
他甚至提出在SO此评论聊天指出多么糟糕传递自己的盐可
请注意,这从php.net
警告
盐选项已被弃用的PHP 7.0.0的。 现在优选的是简单地使用由默认生成的盐。
结论? 忘了盐的选择。
这将是完全够用password_hash('password', PASSWORD_DEFAULT)
*(或_BCRYPT)
你不应该进入自己的盐,盐留下空,函数将产生良好的随机盐。
插入到数据库(或文件或任何你使用)全由该函数返回的字符串。 它包含:算法,成本,盐(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应该是在年底(该用户的密码,而不是之前之后)。