几年后,我在stackoverflow上询问了如何使PHP密码存储安全。 main answer建议使用以下散列算法:
function hash_password($password, $nonce) {
global $site_key;
return hash_hmac('sha512', $password . $nonce, $site_key);
}
答案建议使用随机随机数。有一个随机的随机数比简单的唯一随机数有什么优势吗?
例如,每个用户都可以拥有自己的ID,但不会发生变化。但是,我们假设用户ID是顺序的(使用MySQL的自动增量功能构建),因此不是随机的。用户ID是一个好的nonce还是随机性很重要?
现在,每个用户都可以选择一个用户名。每个用户都有自己的用户名,该用户名不会更改,两个不同的用户不能拥有相同的用户名。 用户名仍然不是随机的,但它们也不是顺序的。用户名是否足够好作为nonce?它会比使用用户ID更好吗?
答案 0 :(得分:2)
这一切都在假设一个NONCE是盐...
如果用nonce表示盐,那么是的,需要更多的彩虹表。通常,超过20个字符的盐就足够了,但是对于极端安全条件,您需要为每个密码添加一个新的随机盐。
慢速哈希http://www.php.net/manual/en/function.hash.php#89574也是不错的选择,没有讽刺。但我喜欢成熟。
没有看到你的回复的下半部分。详细说明:Nonce用于防止使用彩虹表。 ID是否有效仅取决于ID的长度。随机性在技术上并不重要,但只需要更多的彩虹表。例如,假设您使用字符“a”作为随机数,密码长度为2个字符,则必须创建a-aa,a-ab a-ac等的彩虹表。如果你每次都使用一个随机的,那么'a'的所有排列都必须完成+其他随机字符的所有变换。
但总的来说制作彩虹表需要相当长的时间。因此,如果你想出一个很长的盐,很可能它的彩虹表不存在。
答案 1 :(得分:2)
我发现在网上写了一篇关于这个主题的相当不错的教程。我不太清楚谷歌在哪里找到了它,但让我看看我是否可以将自己的功能完全打破,因为它就在我面前......
首先是该函数,它可以创建任意大小的密钥长度。我冒昧地评论它......
function pbkdf2($password,$salt,$iter_count = 1500,$key_length = 32,$algorithm = 'sha512')
{
/*
@param string password -- password to be encrypted
@param string salt -- salt to encrypt with
@param int iter_count -- number of times to iterate blocks
@param key_length -- length of key to return
@param $algorithm -- algorithm to use in hashing
@return string key
*/
//determine the length of the hahs
$hash_length = strlen(hash($algorithm,NULL,TRUE));
//determine the number of key blocks to compute
$key_blocks = ceil($key_length/$hash_length);
//initialize key
$key = '';
//create the key itself
//create blocks
for($block_count = 1;$block_count <= $key_blocks;$block_count++)
{
//initalize hash for this block
$iterated_block = $block = hash_hmac($algorithm,$salt.pack('N',$block_count),$password,TRUE);
//iterate blocks
for($iterate = 1;$iterate <= $iter_count;$iterate++)
{
//xor each iterate
$iterated_block ^= ($block = hash_hmac($algorithm,$block,$password,TRUE));
}
//append iterated block
$key .= $iterated_block;
}
//return the key
return substr($key,0,$key_length);
}
我觉得这可能是最好的方法。也许我太偏执了?
答案 2 :(得分:0)
用于存储足以使用的密码:
sha512(salt + password)
每个用户 salt
应随机且唯一。随机盐将使预先计算的哈希表攻击变得不可能:每个用户都需要自己计算的哈希表。如果你不使用随机盐,那么预先计算的表存在的可能性会更高。
在密码之前定位salt 将有助于隐藏哈希模式,以防某些用户拥有相同的密码。
不需要Nonce ,因为它是用于防止回复攻击。您的架构中无法实现此保护。
使用 HMAC 来防止冲突是没用的,因为a)我们使用哈希不用于MAC,b)使SHA-512 you need to calculate的冲突概率为50%约2 ^ 256值。并且2 ^ 256是真正的天文数字。