为什么网站存储密码的哈希而不是密文?

信息安全 密码
2021-09-08 20:15:21

每次我们讨论密码和散列函数时,海报都会立即提出如何破解散列函数,我们应该避免 MD5 .. 等因此我们使用强密码和盐等措施来避免暴力破解和彩虹表 .. 等

同时,每次我们讨论 TLS 时,人们都会指出几乎不可能破解所使用的加密以及 TLS 的安全性。

那么为什么我们需要散列函数来将密码存储在数据库中呢?让我们把它们加密吗?因为它更安全,让用户享受使用弱密码的乐趣。

假设我们使用非对称加密算法,安全地生成公钥和私钥,然后丢弃私钥。

4个回答

我的理解是,您认为如果通过以下站点存储密码会更安全:

  1. 生成唯一的公钥/私钥对。
  2. 立即以安全的方式处理私钥。
  3. 用公钥加密密码。
  4. 将公钥和加密密码存储在数据库中,类似于存储盐和散列密码的常见做法。

您声称这种密码存储模型比现代技术更安全的说法是错误的。虽然这种方法确实具有密码存储所必需的不可逆性,并且具有足够的预计算防御,但它缺乏防止即使是简单的字典攻击所需的性能防御。

现代密码存储散列算法(如bcryptscrypt)被设计为即使在面对专用硬件时也执行缓慢。另一方面,加密算法被设计为尽可能高性能。因此,破解使用公钥加密的密码的离线字典攻击将比试图破解 bcrypt 或 scrypt 哈希的类似攻击快得多(可能很多数量级)。

TLS 使用公钥和私钥来加密会话。客户端只有包含公钥的证书,但为了使用它,服务器包含私钥。在服务器之外,这种通信是安全的。在服务器内部,攻击者可以学习密钥并解密通信。

如果我们使用公钥/私钥加密来加密密码并且攻击者进入服务器,他们可以学习私钥,然后解密所有密码。

散列没有密钥(尽管它可能使用“盐”。)它通常被称为单向函数,因此与加密不同,它没有“反向”算法。如果你散列数据,你不能轻易地取消散列它。您仍然可以通过尝试您能想到的每个密码来暴力攻击哈希,如果哈希匹配,您已经猜到了。但是没有神奇的价值可以恢复所有的密码。这就是为什么散列比加密更安全地存储密码。

关于 MD5、SHA-1 等中的缺陷,请记住加密散列函数有多种用途,每种暴露的漏洞因用例而异。哈希的一个用途是生成消息摘要,这是一个唯一编号,有助于验证一段文本是否未更改(例如证书上包含的数据)。如果可以使用相同的摘要值伪造第二个文档,那么攻击者可以创建一个虚假的证书并对服务器的所有用户执行中间人攻击。但是,如果在数据库中的两个密码之间发现冲突,则可能只会泄露 Ulkoma 和 JohnDeters 都选择了相同密码的信息。这只会给两个人带来风险,而不是系统的每个用户,这总体上是一个不太严重的问题。

为每个用户生成唯一的公钥(丢弃私钥),然后加密和存储密码的提议,导致系统在功能上等同于使用加盐哈希。攻击者不必破解公钥,他们只需要尝试用公钥加密一堆密码,直到他们得到匹配。

生成密钥对需要时间——即使使用现代计算机,也需要几秒钟。如果您必须生成大量密钥对,则不会花费太多精力来导致服务器性能问题。

此外,为每个存储一个加密的密码和一个密钥将比为每个存储一个散列或一个散列加上一个盐占用更多的存储空间。对于小型网站,这可能不是主要问题,但当您拥有数百万用户时,它就成为一个潜在问题。

实际上,建议的过程是一个散列过程,只是比使用设计用于散列输入的例程效率低。

我们有更好的工具——加密哈希函数——所以这可以被认为是使用电钻作为锤子。它可以工作,并且对于某些工作来说是一个更好的工具,但它比锤子有更多的活动部件和更高的成本,它可以很好地钉入钉子!

如果密文的密钥被暴露,它将使您的数据库受到损害。这些密码可以被解密并用于登录您的站点或用户立即使用相同(或相似)密码的任何其他站点。

安全的加密哈希算法是不可逆的,并且允许有更多时间来管理违规行为,因为它们需要被暴力破解。

我对 TLS 的了解不足以对此发表评论,但这个想法仍然是一样的。使用散列,您只能使用蛮力技术,而使用加密,您只需要访问密钥。

编辑:散列的另一个好处是它可以更好地保护更好的密码在大多数用户使用非常复杂和冗长的密码的情况下,破解许多帐户将变得更加困难。加密会暴露所有密码。