我想在数据库中的密码旁边存储一个(随机)盐。现在,问题是:
我应该存储哈希值还是纯文本?有没有区别(更安全,更快?)?我应该在创建随机字符串方面付出多少努力?
示例代码:
//Creating random salt
$saltchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./:;<=>?@[]^_`{|}~";
$salt = uniqid(rand(), true).str_shuffle($saltchars);
// Or should the salt be hashed (md5 or sha512 for more security)
// $salt = hash('sha512', uniqid(rand(), true).$staticsalt.str_shuffle($saltchars));
//Create user (with salt & pepper)
$sqlquery = "INSERT INTO users (user, password, salt) VALUES('$id','".hash('sha512', $staticsalt.$accesskey.$salt)."','".$salt."');";
$sqlresult = mysql_query($sqlquery);
记录的:登录脚本
$sqlquery = "SELECT salt FROM users WHERE user='$id';";
$sqlresult = mysql_query($sqlquery);
if (mysql_num_rows($sqlresult) == 1) {
$salt = (mysql_fetch_array($sqlresult));
//Check if the password is correct
$sqlquery = "SELECT * FROM users WHERE user='$id' AND password='".hash('sha512', $staticsalt.$accesskey.$salt[0])."'";
$sqlresult = mysql_query($sqlquery);
unset($accesskey, $salt);
//Check whether the query was successful or not
if($sqlresult) {
if(mysql_num_rows($sqlresult) == 1)
{echo 'Login successfull';}
else {die('Error: wrong user ID/password');}
}
}
我知道有许多,可能太多的网站在讨论专业人士和盐的缺点。但是如果盐应该加密,没有人会回答 - 并且没有人展示如何用随机(!)盐编写登录脚本(像我一样保存在数据库中)。
所以作为一个php初学者,我不知道这段代码是否安全?或者,如果有任何技巧可以让它更快或更精简......谢谢!
答案 0 :(得分:4)
没关系。你可以假设盐是公共信息,因为盐攻击有助于防止 - 彩虹表辅助字典攻击 - 如果攻击者已知盐,则不会更容易。你应该问问自己为什么你认为首先加密盐是个好主意。
另外,你应该读到这个:
答案 1 :(得分:3)
由于盐无法进行哈希处理,因此没有人谈论盐被哈希化。如果不明白为什么 - 如果你真的“不知道这段代码是否安全” - 请使用其他人的身份验证系统而不是创建自己的身份验证系统,因为它非常非常容易如果你不知道自己在做什么,就要留下一些安全漏洞。
编辑:
哈希是单向的。您将数据放入。您不会将数据输出。这就是它的用途。如果你把盐放入,你就无法把它拿出来。如果您无法将其删除,则无法将其添加到用户提供的密码中。如果你不能这样做,你不能把它当作盐。
答案 2 :(得分:3)
由于您需要salt来在登录脚本中计算密码哈希值,因此您不能只存储盐的哈希值,因为这将是不可逆转的操作,即原始盐将丢失。
所以我假设你要问的是,从采摘随机字符串得到的原盐是否会产生更好的盐。在这种情况下,使用散列函数与“散列”无关,它只是一种生成更长,看似更随机的序列的方法。然而,这绝对没有意义,因为散列的盐仍然需要存储在数据库中 - 如果你愿意的话,用纯文本!
答案 3 :(得分:0)
salt的目的是让某人不能使用相同的彩虹表来破解所有密码。为每个密码创建一个新的彩虹表只会使该方法效率太低。你不必隐藏盐,隐藏它不会增加安全性。
由于salt不是加密密钥,并且不必隐藏,因此创建它们时不必非常精细。只需使用常规随机生成器来选择一些随机字符。
此外,你无论如何都不能散列盐,因为当有人想登录时你不能用它来检查密码。