6

在对网站的用户进行身份验证时,应该在数据库中还是在网站中进行哈希生成和比较?

我的论点是网站应该将用户提供的密码(可能由网络服务器加密)传递给数据库。然后数据库用盐重新加密它并比较哈希值。无论用户的凭据是否有效,数据库都会响应 Web 服务器。通过这种方式,最小的离开数据库,基本上是或否,没有存储的凭证信息。缺点是,数据库必须做更多的工作。

另一个论点是工作应该在 Web 服务器中完成。在这里,Web 服务器将创建哈希并从数据库中请求存储的哈希并进行比较。在这种情况下,需要将盐从数据库传回 Web 服务器以创建散列。但是,随着网络服务器数量的增加,工作是共享的。

我个人认为第二种方法存在潜在的安全风险。如果 Web 服务器受到威胁,可以从数据库中请求盐和哈希值并轻松破解。

执行上述操作的最佳做​​法是什么?我是否忽略/遗漏了什么?

谢谢

4

4 回答 4

3

这里有一篇关于如何安全存储密码的非常好的文章:

http://throwingfire.com/storing-passwords-securely/

于 2012-06-15T15:09:44.157 回答
3

您忽略了盐的用途。

盐用于防止对散列密码的字典攻击。如果您的密码是“花生”并且哈希为 12345,那么我可以为字典中的每个单词(包括您的密码)预先生成哈希列表,并通过查找我预先生成的密码集来快速找到您的密码哈希。这就是LinkedIn最近发生的事情。如果密码是加盐的,我必须在破坏数据库为每个盐值预先生成一个字典,这将非常昂贵。

此外,适当的随机生成的盐可以防止攻击者知道你和我有相同的密码(没有盐,我们会有相同的哈希)。

我的观点是,这些盐并不是秘密。它们不是公共信息,但攻击者获得盐值 + 哈希值并不一定意味着密码已被泄露。

于 2012-06-15T15:10:50.110 回答
3

我怀疑你会遇到的第一个问题(这是一个大问题)是你的数据库没有密码哈希函数。当然,它可能有 MD5() 和 SHA1() 但这些是加密哈希函数。它有 bcrypt() 或 scrypt() 或 PBKDF2() 吗?

使用加密哈希函数而不是密码哈希函数意味着 LinkedIn 密码可以如此迅速地被破解。如果您不使用上述功能之一,那么如果您的哈希值泄露,您将同样容易受到攻击。


继续回答您的问题,假设您的数据库确实支持密码哈希算法(使用 bcrypt 只是因为我必须选择一个)。两种选择是:

数据库中的哈希:

$db->query("SELECT COUNT(*) FROM users WHERE username = '?' AND password = BCRYPT(?, (SELECT salt FROM user WHERE username = '?'))", $username, $password, $username);
if($row['count'] != 1)
{
  // Not authenticated.  Throw exception.
}

在这种情况下,原始密码被发送到数据库并返回一个简单的是或否(1 或 0)。该数据库通信可以加密。哈希和盐永远不会保存在应用程序中。

应用程序中的散列:

$db->query("SELECT username, salt, password FROM users WHERE username = '?', $username);
if(bcrypt($password, $row['salt']) != $row['password'])
{
  // Not authenticated.  Throw exception.
}

在这种情况下,哈希值和盐值从数据库中提取到应用程序中,原始密码的哈希值和比较在那里完成。与数据库的通信仍然可以加密。原始密码永远不会保存在数据库内存中。

为了提高效率,我们可以假设两种散列算法都是用 C(或某种编译语言)编写的,并且可能由操作系统提供,因此需要相同的时间。应用程序散列选项通过网络接收更多数据,而数据库散列选项发送更多数据并且具有更复杂的查询(本质上是两个查询,一个用于获取盐值,一个用于进行比较)。可能无法按照我编写该查询的方式使用索引,但可以重写该查询。由于这两种情况下的数据大小可能仍然是一个 TCP 数据包,因此速度差异可以忽略不计。由于子查询,我认为这是应用程序哈希选项的胜利。

为了曝光。我认为原始密码比哈希和盐更敏感。因此,限制原始密码的暴露似乎是更安全的选择,使应用程序散列成为最佳实践。

于 2012-06-15T15:14:36.757 回答
0

计算机安全的一个很好的经验法则是,如果你不得不问,你不应该自己做。但是,如果您担心如果 Web 服务器遭到破坏,密码详细信息会被泄露,那么一种方法是将身份验证转移到它自己的系统上,并且根本不让 Web 服务器访问密码数据库。

于 2012-06-15T15:19:30.233 回答