2

所以我一直在阅读很多关于 PHP 加密的内容。以至于我不确定究竟什么是安全存储登录信息的真正好方法。

但是,以下功能是我想出的:

function loginHash($username, $password){
    $salt = str_split($password,(strlen($password)/2)+1);
    $hash = hash('whirlpool', $username.$salt[0].'centerSalt'.$salt[1]);
    return $hash;
}

我做对了吗?它用于验证与用户名组合的密码,以及将生成的哈希与存储在数据库中的哈希进行比较以验证登录的能力。

4

5 回答 5

6

我的建议是永远,永远,永远不要编写自己的加密和哈希函数。即使是专家也总是做错,所以不要自己尝试。

我听说phpass (Openwall)是一个不错的散列框架,我建议你使用它。

他们在哈希中使用盐,并且有相当多的参数来调整哈希。

于 2009-06-21T09:17:47.397 回答
6

加密!=散列。它们都被普遍认为属于密码学的范畴,但是当某些东西可以被加密时,它就可以被解密,而散列则不是这样。散列就是散列,仅此而已。

盐确实构造不正确。它应该是使用 fopen() 调用从 /dev/urandom 读取的 x 字节。例如,16 字节的盐是我个人使用的。这有效地防止了彩虹表攻击。

为了使事情更安全,也请使用密钥。例如:

$hashedPassword = hash_hmac('whirlpool',$password.$salt,$key);

$key 只是随机数据。例如,您可以在文档根目录上方的隐藏文件夹中生成一个名为“key.bin”的 64 kB 文件,并在哈希处理之前使用 file_get_contents()。

为什么要使用密钥?如果您将哈希和盐存储在数据库中,并将密钥存储在文件系统中,那么这可以防止任何人在拿到您存储的哈希和盐时破解您的哈希。因此,攻击者需要同时破解数据库和文件系统来破解您的哈希值,但请注意,如果任何人已经破解了您的整个应用程序,那么破解您的哈希值将毫无意义,这意味着您的哈希方案是好的。

于 2009-06-21T10:05:18.190 回答
5

你实际上并没有使用盐。

Salt 是随机生成的字符串,包含在哈希函数的输入中。因此,每次都会有所不同。

这个想法是当用户存储密码时生成一个盐,并且这个盐包含在您的数据存储中。进行身份验证时,您检索盐和存储的哈希,在给定的密码前加上存储的盐,然后将两者散列在一起。然后将结果与存储的哈希进行比较。

于 2009-06-21T09:19:43.820 回答
1

我认为上面的代码检查了这两个框。

  • 避免彩虹表攻击(通过盐)
  • 安全登录
于 2009-06-21T09:18:22.810 回答
1

使用盐解决了两个问题:

  1. 彩虹表:彩虹表只是预先计算的哈希值,与源值一起存储。通过比较哈希值,您可以得到未经哈希处理的值(密码)。通过添加盐,你得到了另一层复杂性——攻击者必须知道盐才能生成自定义哈希表。

  2. 散列值的差异:没有盐,相同的 2 个密码生成相同的 2 个散列。现在很容易看出两个用户是否使用相同的密码(这里的弱点与彩虹表大致相同,但仍然如此)。这可能不算多,但仍然是一个令人担忧的问题。

此外,您不应该使用快速算法进行密码散列。md5 快,sha 快。越慢越好。

matsano chargen博客是一个很好的(有趣的)资源,提供有关安全性的提示和指针。

于 2009-06-21T11:02:20.183 回答