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

Using crypt(), how does my app validate passwords that have randomly generated salts?

我一直在研究php的crypt函数和stackoverflow的几个问题,我正在尝试找出加盐和散列的密码。

我在php社区页面上找到了:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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.'$');
}
?>

这种情况与以下情况相比如何:

1
2
3
4
5
6
7
8
<?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);
?>

下面是另一个问题的摘录:

However, the PHP crypt() function can
use a variety of different hashes to
compute the hash. When you prefix your
salt with"$1$" you get a hash with an
MD5. When you prefix with $2$ you get
a crypt with blowfish, which is more
secure.

The"$1$" is prefixed to the output so
that the hash can be verified. If it
wasn't included, there would be no way
to know from the stored hash which
algorithm should be used! This
information would have to be stored
elsewhere. To save you this trouble
PHP includes the algorithm in the hash
output.

我脑子里有点乱,涉及哈希、加密和盐类…但真正困扰我的是,我如何比较一个用户输入的password和一个salted hashed password,如果盐是在用户创建时随机生成的…而且不存储——除此之外,如果您必须指定正确的前缀才能在用户返回时再次验证密码,那么在自动化salt中使用crypt()有什么意义呢?


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

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

编辑:您的salt应该包含(加密安全-)随机字节。现在,您限制它只包含字母和数字


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

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

盐实际上与密码一起存储。{enctype}是正在使用的加密类型,{salt}是salt。因为您知道加密类型和salt,所以您可以使用它们提供的密码自然地复制散列(从而对用户进行身份验证)。

用于crypt(供参考)的{enctype}值的简便表:

1
2
3
4
5
6
7
8
          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)

最后,PHP如何允许您使用它们。

所以,如果你看到一个像这样的字符串:

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

你知道你在和沙-512打交道,盐是"foobar"(很可能,账户也是foobar!).

这是一个盐是如何储存和与哈希关联的例子。正如Slaks所说,不要将盐限制为ASCII码。至少应该从prng或hrng获取字节,只有在没有rng可用时才返回time()。


其想法是为每个用户/密码提供一个随机的salt。

添加salt只会使猜测密码变得更加困难,但是对每个帐户使用随机salt会增加安全性,因为它会减少攻击者猜测任何其他密码的方式,正如给定的一些当前和不安全的密码和/或用户名一样,反向工程猜测密码很容易。

它对跨系统安全性有很大的影响,因为人们往往在大多数站点上使用用户名/密码。

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


不,你做错了。使用solardesigner的phpass进行哈希和验证。最后,永远不要使用你自己的特别计划,这样做是自找麻烦。