如果散列的密码在DB中,则小人可以在login时使用input框中的密码

我读了这是模块(bcrypt)用来做login,密码保存的东西。 就我的理解而言,它解决的主要问题是,如果黑客访问您的数据库,并且不散列密码,黑客就可以轻松地复制和粘贴用户名和密码并访问该帐户。 该模块提供了比较散列string和通过req.body.password发送的密码的req.body.password

我对哈希的理解是,它需要一个文本,并创build一串长长的随机字符。 在string存储在mongoDB password字段中的应用程序中,如何防止黑客将随机string复制并粘贴到input框中并如此login? 所以我没有看到哈希的问题。

底漆

好的,让我们先看看究竟发生了什么(在最佳情况下,虽然稍微简化):

  1. 用户创build一个新的密码。
  2. 您的应用程序散列密码并保存散列密码以供进一步阅读
  3. 如果用户login,则应用程序将获取用户提供的密码,并通过bcrypt运行该密码,该密码散列该密码,然后将该散列密码与存储的密码进行比较。 如果它们匹配,则通过login提供的密码与创build密码时提供的密码相同 – 这是您唯一需要知道的事情。

所以,清楚地说明一下,我们必须看看不同的攻击场景。

攻击者获得了对数据库的读取权限

好的,攻击者可以读取数据库。 够坏。 个人资料泄露。 其实他可以复制所有的数据。 但是让我们把它放在一边,看看密码。 攻击者可能会看到像这样的东西

 Username Password admin $2a$04$acaUVljoRAvazzj6YX7K2eEfUt9PHVVgr.ahZ4xLzb9292u4Bv9Sm jdoe $2a$04$cTUGYHixAGwdTU90XflsI.G2FQuj/p4nVYW2Tp3HsCeUGs5MPmR.e 

现在,当且仅当蛮力是从散列值计算input数据的最简单方法时,散列函数被认为是密码安全的。 利用今天的散列大小和计算能力,您需要长时间才能从哈希计算密码。

按照上面描述的过程,当我们的攻击者已经读取数据库时,他不能简单地将哈希值作为密码粘贴 – 应用程序将采取散列,再次散列,随后的匹配检查将失败。 好处?

  1. 在正常操作期间,即使pipe理员也不能读取用户select的密码。 人们倾向于在多个实例上使用密码。 我们都知道我们不应该这样,但事实恰恰相反。 你想让SOpipe理员知道你select的密码吗? ;)攻击者less多less?
  2. 由于攻击者无法通过获取哈希值来login,因此他无法代表合法用户某件事,例如买东西。
  3. 如果攻击者想暴力破解哈希值以获取明文密码,则必须投入大量资源。 给你一个印象:假设我们可以做65536个哈希/ s,我们有2 232个可能性,所以我们需要〜2.18 * 10 62 来蛮横的哈希,这个大约是1.59 * 10 52的年龄宇宙。 即使有很多内核正在进行并行处理(也就是说整个行星系统转换为计算机),这将需要非常非常长的时间。
  4. 攻击者将无法识别相同的密码,因为使用bcrypt,即使相同的input数据也不会产生相同的散列值 – 这是相当先进的散列algorithm。 上面的两个哈希是由相同的input创build的 。 这是有效的,因为每个散列都包含它自己的(伪随机生成的,iirc) 盐 。 这将迫使攻击者对每个find的盐值进行暴力攻击,以确定相同的值或清除文本值。

所以,通过散列,我们已经使得读取访问权限的攻击者不可能仅仅通过查看散列值(其他的看起来是散列值)来获取有关密码的任何信息。

攻击者获得对数据库的写入权限

好的,你正在使用。 攻击者获得了写入权限。 他可能会破坏你的应用程序,复制所有的数据,然后删除它。 希望你有你的备份电stream和工作。

现在他可以简单地为“admin”和“jdoe”设置一个新的bcrypt散列,他可以做任何事情,这些用户可以做。 卫生署!

但是让我们看看他不能做什么:与读访问一样,他不能计算给定散列的明文密码。 因此,即使用户在您的应用程序中使用了相同的密码,攻击者也无权访问用户的Maskbook,Gibber或Instanonsense帐户。

结论

通过存储bcrypt密码哈希,我们有几个好处:

  1. 密码是从pipe理员隐藏的
  2. 即使攻击者获得散列值,他也不能轻易计算明文密码
  3. 攻击者不能对相同的密码进行任何推理,因为即使input相同,每个input值也会产生不同的哈希值。 所以他必须为每个盐值做一个蛮力。 往上看。
  4. 当攻击者只获得读访问权限时,他不能访问应用程序。

希望能够使存储哈希密码的优点变得清晰。

正如你所说的,函数将创build一个从传递给它的string的散列。 哈希不是随机的,而是混洗的input,使用相同的algorithm和input结果将是相同的,它不能被解码。 如果试图散列哈希密码将产生完全不同的东西。

 md5('password') = '5f4dcc3b5aa765d61d8327deb882cf99' md5('5f4dcc3b5aa765d61d8327deb882cf99') = '696d29e0940a4957748fe3fc9efd22a3' 

当用户想要login时,他需要发送原始密码 。 然后您的应用程序将再次计算密码的散列,并将其与存储的散列进行比较。 如果用户发送散列,应用程序会再次计算散列,并且与数据库中的值不匹配。

也许你的困惑来自使用JavaScript,它表明你计算哈希客户端。 尽pipe散列应该在服务器端完成,但是通过互联网发送原始密码而不是散列。

那么如果你的密码,用户名和哈希string存储在数据库中,那么黑客可以使用这个哈希来解密所有的东西。 但是,如果有人嗅探你的login/连接,那么他们将不会以纯文本的方式得到你的用户名和密码,也不会得到散列键。