我使用phpass来生成随机盐和密码哈希,但我的问题是,对于密码重置之类的事情,我创建了一个唯一的令牌。基本上,我抓取16字节的随机数据,然后通过sha256哈希传递它。这是一个好的做法,还是我应该坚持使用16字节的数据
private static function get_random_bytes($count) {
$output = '';
if (is_readable('/dev/urandom') &&
($fh = @fopen('/dev/urandom', 'rb'))) {
$output = fread($fh, $count);
fclose($fh);
}
$random_state = microtime();
if (function_exists('getmypid'))
$random_state .= getmypid();
if (strlen($output) < $count) {
$output = '';
for ($i = 0; $i < $count; $i += 16) {
$random_state =
md5(microtime() . $random_state);
$output .=
pack('H*', md5($random_state));
}
$output = substr($output, 0, $count);
}
return $output;
}
如果随机数据是加密强的,它应该是,那么不需要对它进行哈希。
如果你的数据不是加密强的,比如用rand()
检索的值,那么哈希可能稍微更安全,但好处是最小的,你应该使用更强的PRNG。
在这种情况下,唯一可能的安全漏洞是如果有人
- 使用sql注入从数据库中提取所有密码和盐,
- 在盐生成中发现了一个模式,
- 根据预测的盐分制作彩虹表,
- 再次从数据库中获取数据,
- 使用彩虹表从数据库中破解大量密码
所以基本上,不,它不会增加安全性。此外,您上面的代码使用了/dev/urandom,它提供了非常强的随机性,因此由于上面列出的第2步或多或少不可能实现,因此好处甚至进一步减少。唯一受到猛烈攻击的组织是国家安全局、中央情报局和类似的组织。
是的,为密码重置令牌散列随机数据绝对可以提高安全性。
非散列令牌可以帮助破坏帐户的场景:
攻击者- 获得对数据库的读访问权限,
- 等待令牌出现在密码重置令牌表
<g>
中, 获取令牌、关联的电子邮件地址和工艺品URL
http://example.com/password_reset?t=gobble-dee-goo-token
现在可以修改关联邮箱的密码
通过phpass散列,即使攻击者获得了对数据库的读访问权,密码重置功能也不能用来破坏帐户。这是因为他们不能使用令牌的哈希值来制作URL。