使用crypt(),我的应用程序如何验证随机生成盐的密码?

时间:2011-01-30 23:27:12

标签: php hash passwords

我一直在关注Stackoverflow上的PHP's crypt function和一些questions,我正在尝试找出盐渍和散列密码。

我在PHP社区页面上找到了这个:

<?php
function md5crypt($password){
    // create a salt that ensures crypt creates an md5 hash
    $base64_alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                    .'abcdefghijklmnopqrstuvwxyz0123456789+/';
    $salt='$1$';
    for($i=0; $i<9; $i++){
        $salt.=$base64_alphabet[rand(0,63)];
    }
    // return the crypt md5 password
    return crypt($password,$salt.'$');
}
?>

这样的事情与以下相比如何:

<?php
// Slightly modified example from PHP community page

$password = trim(mysql_prep($_POST['password']));

// Get the hash, letting the salt be automatically generated
$hashed_password = crypt($password);
?>

以下是另一个question的摘录:

  

但是,PHP crypt()函数可以   使用各种不同的哈希来   计算哈希值。当你的前缀   盐与“$ 1 $”你得到哈希与   MD5。当你得到$ 2 $的前缀时   河豚的地穴,更多   安全

     

“$ 1 $”以输出为前缀   可以验证哈希值。如果它   不包括在内,没有办法   从存储的哈希中知道哪个   应该使用算法!这个   必须存储信息   别处。为了省你这个麻烦   PHP在哈希中包含算法   输出

我的头脑有点关于哈希,加密和盐......但真正让我感到困惑的部分是如何将用户输入的passwordsalted hashed password进行比较,如果salt是在用户创建时随机生成的......而不是存储的 - 除此之外,如果您必须指定正确的前缀以便能够再次验证密码,那么将crypt()与自动盐一起使用的重点是什么?用户退货后?

4 个答案:

答案 0 :(得分:5)

您需要与用户一起存储盐。

盐的目的是确保具有相同密码的两个用户获得不同的哈希值 这可以防止彩虹表攻击。

编辑:您的salt应包含(加密安全)随机字节
现在,您将其限制为仅包含字母和数字

答案 1 :(得分:1)

我们的想法是为每个用户/密码设置一个随机盐。

添加盐只会让您更难猜测您的密码,但是为每个帐户使用随机盐会增加安全性,因为它会减少攻击者猜测任何其他密码的方式,因为一些当前和不安全的密码密码和/或用户名,猜测密码的逆向工程很容易。

它对跨系统安全性有很大影响,因为人们倾向于在大多数网站上使用名称用户名/密码。

使用随机盐使用字典几乎不可能进行攻击,因为您需要计算每种可能的盐来猜测任何密码。

答案 2 :(得分:1)

如果仔细查看/ etc / shadow的格式,您将在第二个字段中看到命名法(:分隔字段):

username:${enctype}${salt}$HoPeFuLlYVerYloNGpassWOrDhAsh: ... ... ... 

盐实际上是用密码存储的。 {enctype}是使用的加密类型,{salt}是盐。由于您知道加密类型和salt,您可以自然地使用它们提供的密码重现哈希(从而验证用户)。

用于crypt的{enctype}值的便捷表(用于提供信息):

          ID  | Method
          ─────────────────────────────────────────────────────────
          1   | MD5
          2a  | Blowfish (not in mainline glibc; added in some
              | Linux distributions)

          5   | SHA-256 (since glibc 2.7)
          6   | SHA-512 (since glibc 2.7)

最后,how PHP lets you use them

所以,如果您看到如下字符串:

root:$6$foobar$JKLsdiuoilI/KSJHDKUyjh/SHDKJyUYW(....)

你知道你正在处理SHA-512而且盐是'foobar'(很可能,这个帐户也是foobar!)。

这是(一个)如何储存盐并与散列相关联的例子。正如SLaks所说,不要将盐限制为ASCII。至少你应该从PRNG或HRNG获得字节,当没有RNG可用时,只能回到时间()

答案 3 :(得分:0)

不,你做错了。使用solardesigner的PHPASS进行散列和验证。最后,永远不要使用自己的临时方案,这样做就是在寻找麻烦。