为webservice提供密码的原因

时间:2018-01-04 12:53:44

标签: hash passwords salt

我有与用户管理相关的非常基本的问题,特别是存储散列密码。 我看了几页(比如https://wiki.python.org/moin/Md5Passwords)。 我理解哈希的方式是:

  • 用户提供的密码是单向散列(具有任何功能)。
  • 无人(包括用户/管理员)能够看到密码。
  • 当用户登录时 - 对他提供的字符串进行哈希处理以查看它是否与存储的哈希密码相匹配。

这一切都很清楚,但我不确定哈希中的'盐'是什么。 我读os.urandom(Python)很好创造好盐: https://crackstation.net/hashing-security.htm

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

有人可以提示我如何使用盐吗?我的理解是否正确。我需要在某处储存“盐”吗?

在我发布此问题之前,我发现了这个: Should the Salt for a password Hash be "hashed" also?

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

1 个答案:

答案 0 :(得分:1)

Salt用于防止黑客将密码哈希值反转密码。所以在这里我们假设黑客可以访问数据库。

没有盐

让我们首先假设没有盐的情景。在这种情况下,表格如下:

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

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

黑客当然想知道d3b0731932ff背后的密码是什么。哈希函数是一个方向,在某种意义上我们可以非常快速地对密码进行哈希处理,但是如果它是一个很好的哈希函数,那么它将会发挥作用 - 在猜测了大量的哈希值之后需要很长时间密码。

因此,没有太多希望轻松检索d3b073背后的可能密码。但我们可以轻松找到100个最流行的密码列表,并计算所有这些密码的MD5哈希值。这样的清单看起来像:

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

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

现在重点是我们可以构建这样的表一次,然后用它来破解所有用户的所有密码。为100和39密码构建这样的表可能需要几个小时,但随后我们可以轻松检索所有密码。所以黑客可以构建(或下载)这样的表(有更有效的方法,例如使用 rainbow tables ),然后每次他/她攻击网站时使用它,然后获取密码所有用户。

含盐

如果我们使用腌制,表格可能如下所示:

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

所以,如果用户2的密码是foo,那么我们计算fooc2a67c的哈希值(或者我们使用另一种方法来组合盐和密码)并存储进入数据库。

重点是很难猜出密码,因为b36232不是foo的散列,而是fooc2a67c的散列,而盐通常是某些东西(伪) - 随机。我们当然可以再次构建最受欢迎的100� 000密码并附加盐c2a67c,但由于我们事先无法知道 salt ,我们无法创建此表只有一次。即使我们很幸运并且已经构建了盐c2a67c的表格,但它也无法帮助我们破解用户1的密码,因为用户1有不同的盐。

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

我们当然可以决定计算所有可能盐的所有哈希值,例如:

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

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

基本上盐可以作为扩大密码空间的一种方式。即使您在两个网站上输入相同的密码,网站的个人盐也会(接近确定)是唯一的,因此哈希也是唯一的。