当前位置: 首页 > 知识库问答 >
问题:

为webservice加盐密码的原因

吴凯泽
2023-03-14

我有一个非常基本的问题,涉及到用户管理,尤其是存储散列密码。我读了几页(比如https://wiki.python.org/moin/Md5Passwords ). 我对哈希的理解是:

  • 用户提供的密码是单向散列的(使用任何函数
  • 没有人(包括用户/管理员)能看到密码
  • 当用户登录时,他提供的字符串将被散列,以查看它是否与存储的散列密码匹配

这一切都很清楚,但我不确定哈希中的“salt”是什么意思。我读os。urandom(Python)很适合制作优质盐:https://crackstation.net/hashing-security.htm

我不确定的是,如果我用salt和它的单向散列用户密码,该如何使用这个添加的“salt”。下次用户登录时,他只知道密码,不知道盐。由此,我假设为这个用户生成的“盐”需要存储在某个地方。否则就没有意义了。但另一方面,如果有人访问数据库,就会看到“salt”和散列密码。在这种情况下,“salt”不会增加太多价值(它与散列纯密码几乎相同)。所以,也许“盐”只是为了防止前端受到保护(对抗暴力)。

有人能给我一个如何使用盐的提示吗?我的理解正确吗?我需要在某个地方储存“盐”吗?

在我发布这个问题之前,我发现了这样一个问题:密码散列的盐是否也应该被“散列”呢?

盐的附加值是什么?如果我编写Web服务,我可以在3次失败尝试后阻止每个登录。前端没有人能够看到散列值。没有人可以使用暴力(这可能只是DoS,因为3个失败的日志将阻止用户)。黑客需要访问DB并查看散列密码。但如果他有,他会看到“盐”。

共有1个答案

丰博
2023-03-14

Salt用于防止黑客将密码哈希转换为密码。所以这里我们假设黑客有权访问数据库。

让我们先假设没有盐的情况。在这种情况下,该表如下所示:

user | md5 password (first 6 chars)
-------------------------------
   1 | 1932ff
   2 | d3b073

(我们在这里使情况比实际情况更简单)

黑客当然想知道d3b0731932ff背后的密码是什么。哈希函数是一个方向,从某种意义上说,我们可以非常快地散列密码,但是在猜测大量密码后,消除它会——考虑到它是一个很好的散列函数——需要很长时间。

因此,很容易检索d3b073后面的可能密码的希望不大。但是我们可以很容易地找到100,000个最流行密码的列表,并计算所有这些密码的MD5哈希。这样的列表可能看起来像:

password | md5 (first 6 characters)
--------------------------------------------
foo      | d3b073
bar      | c157a7

显然,用户2使用了foo作为密码。我们不知道用户1的密码(但我们知道它不是foobar)。

现在的重点是,我们可以构造这样的表一次,然后使用它来破解所有用户的所有密码。为10万个密码构建这样的表可能需要几个小时,但这样我们就可以轻松检索所有密码。因此,黑客可以构建(或下载)这样的表(有更有效的方法,例如彩虹表),然后在每次入侵网站时使用它,然后获得所有用户的密码。

然而,如果我们使用盐渍,桌子可能会像这样:

user | salt   | hashed password
-------------------------------
   1 | a91f40 | 1a604e
   2 | c2a67c | b36232

因此,如果用户2的密码是foo,那么我们计算fooc2a67c的哈希值(或者我们使用另一种方式将salt和密码组合起来),并将其存储到数据库中。

关键是很难猜出密码,因为b36232不是foo的散列,而是fooc2a67c的散列,而salt通常是(伪)随机的。当然,我们也可以用saltc2a67c构建最流行的10万个密码,但由于我们无法提前知道salt,因此我们不能只创建一次此表。即使我们很幸运,并且已经为saltc2a67c构建了表,它也不会帮助我们破解用户1的密码,因为用户1有不同的salt。

所以解决这个问题的唯一方法是为每个用户构造一个反向哈希查找表。由于一次构造这样的表通常非常昂贵,因此为每个用户计算这样的表并不容易。

当然,我们可能会决定计算所有可能的盐的所有散列,例如:

password  | md5 (first 6 characters)
---------------------------------------------
foo000000 | 367390
foo000001 | eca8ea
foo000002 | 6eb7bf
foo000003 | 7906b1
foo000004 | 0e9f0c
foo000005 | 0bfb11
...       | ...

但是正如你所看到的,这样的表的大小会变得非常大。此外,这需要数千年的时间。即使我们只添加一个十六进制字符作为盐,表的大小也会缩放16倍。是的,有一些技术可以减少这样的表的时间和空间,但是通过增加“密码空间”,破解密码的问题肯定会更加困难。此外,盐通常是大量的字符(或字节)长,这使得它比仅仅16倍更难。

基本上,salt是一种扩大密码空间的方法。即使你在两个网站上输入了完全相同的密码,网站的个人密码(几乎可以确定)也是唯一的,因此哈希也是唯一的。

 类似资料:
  • 创建随机盐。 使用SALT加密密码。 保存用户的salt和加密密码。 我想要盐的大小,算法给出作为输入。 我想要解密的原因是,我有一些为应用程序创建的配置文件和一些值是密码,我想要保存为加密的文件和解密时,我想要使用它。 谁能提供一个适当的例子或如何使用它在我自己的方式?我想实现Jasypt在文章中提到的。但没有可用的代码。

  • 虽然我理解加盐和散列密码过程背后的神学,但我不太理解方法论。据我所知,这个问题及其相关答案中列出的方法,以及MSDN的这篇文章,都经历了创建不同长度的salt的步骤,以便在散列给定密码的过程中使用。 但是,稍后检查密码怎么样?据我所知,再次创建哈希将导致生成全新的盐,最终导致在尝试登录时验证失败。 我是否错过了盐或盐配方的保存位置?还是我不太了解这个过程?

  • 我正在为Web应用程序制作登录系统。要将密码存储在数据库中,我正在使用sha256加密密码,如下所示: 在数据库中,我存储了用户、用户密码和用于散列和验证用户登录的salt。现在,我正在向用户发送包含您的密码的电子邮件,但是当用户收到电子邮件时,由于存储在sha256加密密码中,用户收到的是一个长字符串,而不是用户应该知道的密码。 我的问题是,我可以通过任何方法向您发送实际的用户密码和非密码加密,

  • 因此,在ASP.NET中, 将创建一个每次都唯一的散列加盐字符串。这是伟大的;这意味着,如果有人设法获得了哈希密码(例如,在SQL注入攻击中),他们将无法使用查找表来查找原始密码。然而,据我所知,他们仍然能够轻松地编写代码,试图在本地强行使用它,而不涉及受害者的服务器,例如: …,还是因为某种原因,这毫无意义?在我看来,让上述暴力攻击变得更加困难是值得的,但我从未在的用法示例中看到过这种想法,所以

  • 注意:为了讨论的目的,假设应用程序和数据库存储在单独的机器上,不共享密码等。因此数据库服务器的破坏并不自动意味着应用程序服务器的破坏。

  • 我正在使用。NET Bcrypt哈希实现来自第三方库,它具有创建哈希的方法,只需提供文本或密码,如下所示。 我知道生成的hash包含salt信息,但在创建hash时它没有获取salt参数。 Bcrypt在内部创建随机盐并使用它? 如果我不使用salt重载方法,它会导致安全漏洞吗?