在散列之前将垃圾数据附加到用户密码会影响安全性吗?

信息安全 密码
2021-09-07 18:03:49

我在网站上看到过类似的问题,但不是这个确切的问题。

最接近的一个是在存储接受的答案总结之前更改密码,说明转换密码会浪费 CPU 周期,否则可能会在您的实际散列中进入更高的迭代计数。

虽然这是正确的,但请考虑以下情况:

假设您的应用程序将一个主机用于应用程序代码,另一台主机用于数据库/存储。将来某个时候,您的数据库可能会受到威胁,但您的应用程序代码将保持机密。

如果发生这种情况,攻击者可能会尝试使用暴力破解或带有正则表达式的单词列表来揭示用户密码,这可能会发现至少一些密码,并且随着时间的推移会发现更多密码。

显然,如果您发现您的数据库已被入侵,您将重置所有用户密码。但是在它实际被入侵和你发现它之间的增量时间里,攻击者有一个潜在的攻击向量来访问某些用户的易受攻击的帐户。

所以我一直在想,特别是对于这种情况,在散列之前简单地将一些垃圾数据附加到用户密码会使这个攻击向量变得更弱吗?(即让攻击者更难在您发现发生的事情并重置密码之前及时泄露任何密码)

我不是在谈论一般转换,而是专门关于附加,因为: 1. 它确保所有密码在修改后保持唯一,因此不会丢失熵。2. 在服务器接受注册表单和格式化响应的过程中,这是一个成本相对较低的计算任务。3. 简单,不会增加代码复杂度,使应用程序在未来更难维护。

要附加的字符串将是一个常量字符串,存储在应用程序代码中的一个位置。显然,如果应用程序代码被泄露,那么整个事情就毫无意义了。但是,如果只有用户密码哈希被泄露:

  1. 这对于减缓攻击者的速度是否有效?(即使用现代方法使显示用户密码的时间更长)

而且,一般来说:

  1. 这会在系统中引入任何新的漏洞吗?

例子:

应用服务器有一个常量字符串:"!@#$%^& (),;" User A使用密码 "secretpassword" 注册服务器将两者连接起来,创建: "!@#$%^& (),;secretpassword" 然后对新字符串进行 bcrypt,并将生成的哈希存储在数据库中。

对于以后的每次登录尝试,在重新计算哈希之前,将在用户密码的开头(在服务器上)附加常量字符串。

现在假设我有一百万个用户,攻击者获得了一百万个密码哈希值,我的应用程序使用这些哈希值对用户进行身份验证。攻击者还知道我在服务器上的用户密码开头附加了一个常量字符串,实际上我在我的注册 GUI 上公开说明了它。但是,攻击者不知道我要附加的实际字符串。

的帐户会User A更安全吗(即攻击者需要更长的时间才能显示他原来输入的密码“secretpassword”或找到登录他们帐户并掌握他们的数据的方法)还是会一样?其他User X用户现在是否会因为这种变化而变得不那么安全,或者其他用户不会受到更糟的影响?

1个回答

你所提议的叫做pepper. 它是另一种盐,但不储存。这不会有多大帮助,因为根据Kerckhoffs 的原则,您必须假设攻击者知道您系统上的所有内容,除了密钥。在这种特殊情况下,假设攻击者可以读取每一个文件、数据库上的每条记录和每条日志。他只是不知道用户的密码。

如果您的系统开放注册,攻击者甚至可以注册自己,读取数据库,获取自己的散列密码,并暴力破解秘密字符串。如果每个哈希的字符串都相同,那么一旦他发现密码的秘密字符串,您所有的百万用户也会受到损害。

您不能根据一旦被破坏就立即永远失去所有可用性的东西来计划安全性。一旦发现秘密字符串,您的所有密码都容易受到攻击,您不能只是更改它。您将不得不等待所有用户登录,获取每个用户的明文密码,更改秘密字符串,然后重新散列它。您的所有用户重新登录可能需要数月或数年。当然,除非您进入完全的核心不安全模式并将明文密码也存储在某处。

您将通过使用强大的散列函数并在散列过程中添加更多轮次来提高安全性,而不是通过在密码或散列上添加任何内容或两者兼而有之。