所以我一直在阅读很多关于PHP加密的内容。这么多,我不确定什么是安全存储登录信息的真正好方法。
但是,我提出了以下功能:
function loginHash($username, $password){
$salt = str_split($password,(strlen($password)/2)+1);
$hash = hash('whirlpool', $username.$salt[0].'centerSalt'.$salt[1]);
return $hash;
}
我是以正确的方式做到的吗?它用于验证密码和用户名,并能够将生成的散列与存储在数据库中的散列进行比较以验证登录。
答案 0 :(得分:6)
我建议永远不要永远不要编写自己的加密和哈希函数。即使专家也一直都做错了,所以不要自己尝试。
我听说phpass (Openwall)是一个不错的哈希框架,我建议你使用它。
他们在哈希中使用salt并且有相当多的参数来调整哈希值。
答案 1 :(得分:6)
加密!=哈希。它们通常被认为属于密码学类别,但是当某些东西可以被加密时,它可以被解密,而Hashing则不是这种情况。哈希只是哈希,就是这样。
盐确实没有正确构造。它应该是从/ dev / urandom读取的x字节,并带有fopen()调用。例如,我个人使用的是16字节的盐。这有效地防止了彩虹表攻击。
为了使事情更安全,也要使用密钥。例如:
$hashedPassword = hash_hmac('whirlpool',$password.$salt,$key);
$ key只是随机数据。例如,您可以生成64 kB文件,在文档根目录上方的隐藏文件夹中称为“key.bin”,并在哈希处理之前使用file_get_contents()。
为什么要使用密钥?如果将哈希值和盐存储在数据库中,并将密钥存储在文件系统中,那么这可以防止任何人破解哈希,如果他们得到你存储的哈希和盐。因此,攻击者需要破解数据库和文件系统以破解哈希值,但请注意,如果他们已经破解了整个应用程序,那么任何人破解哈希都是没有意义的,这意味着你的哈希方案是好的。
答案 2 :(得分:5)
你实际上并没有使用盐。
Salt是随机生成的字符串,它包含在哈希函数的输入中。因此,每次都会有所不同。
这个想法是当用户存储密码时生成salt,并且该salt包含在数据存储中。在进行身份验证时,检索salt和存储的哈希值,在给定密码前加上存储的salt,并将两者一起哈希。然后将结果与存储的哈希进行比较。
答案 3 :(得分:1)
我认为上面的代码检查了两个框。
答案 4 :(得分:1)
使用salt解决了两个问题:
彩虹表:彩虹表只是预先计算的哈希值,与源值一起存储。通过比较哈希值,您可以获得未哈希值(密码)。通过添加盐,您将获得另一层复杂性 - 攻击者必须知道用于生成自定义哈希表的salt。
散列值的差异:没有salt,相同的2个密码生成相同的2个哈希值。现在很容易看出两个用户是否使用相同的密码(这里的弱点与彩虹表大致相同,但仍然如此)。这可能不会太多,但仍然是一个值得关注的问题。
另外,您不应该使用快速算法进行密码散列。 md5很快,沙很快。越慢越好。
matsano chargen博客是关于安全性的提示和指针的一个好的(和有趣的)资源。