盐:哈希或纯文本?

时间:2011-07-02 19:17:24

标签: php database hash

我想在数据库中的密码旁边存储一个(随机)盐。现在,问题是:

我应该存储哈希值还是纯文本?有没有区别(更安全,更快?)?我应该在创建随机字符串方面付出多少努力?

示例代码:

    //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初学者,我不知道这段代码是否安全?或者,如果有任何技巧可以让它更快或更精简......谢谢!

4 个答案:

答案 0 :(得分:4)

没关系。你可以假设盐是公共信息,因为盐攻击有助于防止 - 彩虹表辅助字典攻击 - 如果攻击者已知盐,则不会更容易。你应该问问自己为什么你认为首先加密盐是个好主意。

另外,你应该读到这个:

答案 1 :(得分:3)

由于盐无法进行哈希处理,因此没有人谈论盐被哈希化。如果不明白为什么 - 如果你真的“不知道这段代码是否安全” - 使用其他人的身份验证系统而不是创建自己的身份验证系统,因为它非常非常容易如果你不知道自己在做什么,就要留下一些安全漏洞。

编辑:

哈希是单向的。您将数据放入。您不会将数据输出。这就是它的用途。如果你把盐放入,你就无法把它拿出来。如果您无法将其删除,则无法将其添加到用户提供的密码中。如果你不能这样做,你不能把它当作盐。

答案 2 :(得分:3)

由于您需要salt来在登录脚本中计算密码哈希值,因此您不能只存储盐的哈希值,因为这将是不可逆转的操作,即原始盐将丢失。

所以我假设你要问的是,从采摘随机字符串得到的原盐是否会产生更好的盐。在这种情况下,使用散列函数与“散列”无关,它只是一种生成更长,看似更随机的序列的方法。然而,这绝对没有意义,因为散列的盐仍然需要存储在数据库中 - 如果你愿意的话,用纯文本!

答案 3 :(得分:0)

salt的目的是让某人不能使用相同的彩虹表来破解所有密码。为每个密码创建一个新的彩虹表只会使该方法效率太低。你不必隐藏盐,隐藏它不会增加安全性。

由于salt不是加密密钥,并且不必隐藏,因此创建它们时不必非常精细。只需使用常规随机生成器来选择一些随机字符。

此外,你无论如何都不能散列盐,因为当有人想登录时你不能用它来检查密码。