Hash 为webservice设置密码的原因

Hash 为webservice设置密码的原因,hash,passwords,salt,Hash,Passwords,Salt,我有一个非常基本的问题,涉及到用户管理,特别是存储散列密码。 我读了几页(比如)。 我对哈希的理解是: 用户提供的密码是单向散列的(使用任何函数) 没有人(包括用户/管理员)能够看到密码 当用户登录时-对其提供的字符串进行哈希处理,以查看它是否与存储的哈希密码匹配 这一切都很清楚,但我不确定哈希中的“salt”是什么意思。 我读到os.Uradom(Python)很好地创建了好的salt: 我不确定的是如何使用添加的“盐” 如果我用salt和它的单向散列用户密码。下次用户登录时,他只知道密

我有一个非常基本的问题,涉及到用户管理,特别是存储散列密码。 我读了几页(比如)。 我对哈希的理解是:

  • 用户提供的密码是单向散列的(使用任何函数)
  • 没有人(包括用户/管理员)能够看到密码
  • 当用户登录时-对其提供的字符串进行哈希处理,以查看它是否与存储的哈希密码匹配
这一切都很清楚,但我不确定哈希中的“salt”是什么意思。 我读到os.Uradom(Python)很好地创建了好的salt:

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

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

在我发布此问题之前,我发现:

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

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

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

user | md5 password (first 6 chars)
-------------------------------
   1 | 1932ff
   2 | d3b073
(我们在这里使情况比实际情况更简单)

黑客当然想知道
d3b073
1932ff
背后的密码是什么。散列函数是单向的,因为我们可以快速散列密码,但如果它是一个好的散列函数,那么在猜测大量密码后,取消对密码的散列将花费很长时间

因此,很难在
d3b073
后面轻松检索可能的密码。但是我们可以很容易地找到10万个最流行密码的列表,并计算所有这些密码的MD5散列。这样的列表可以如下所示:

password | md5 (first 6 characters)
--------------------------------------------
foo      | d3b073
bar      | c157a7
显然,用户
2
使用了
foo
作为密码。我们不知道用户
1
的密码(但我们知道它不是
foo
bar

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

加盐 但是,如果我们使用盐渍,桌子可能会如下所示:

user | salt   | hashed password
-------------------------------
   1 | a91f40 | 1a604e
   2 | c2a67c | b36232
因此,这里如果用户
2
的密码是
foo
,那么我们计算
fooc2a67c
的哈希值(或者我们使用另一种方式组合salt和密码),并将其存储到数据库中

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

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

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

password  | md5 (first 6 characters)
---------------------------------------------
foo000000 | 367390
foo000001 | eca8ea
foo000002 | 6eb7bf
foo000003 | 7906b1
foo000004 | 0e9f0c
foo000005 | 0bfb11
...       | ...
但正如你所看到的,这样的桌子的大小将增长到巨大的尺寸。此外,这将需要数千年的时间。即使我们只添加一个十六进制字符作为salt,表的大小也会缩放16倍。是的,有一些技术可以减少此类表的时间和空间,但是通过增加“密码空间”,破解密码的问题肯定会更加困难。此外,salt通常有大量的字符(或字节)长,这使得它比仅仅16倍还要难


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

salt也存储在数据库中。使用salt很有用的原因是为了防止黑客使用预计算的哈希。例如,很容易获得前10万个已使用密码的列表,以及md5哈希。md5已损坏。无论是否加盐,都不能将其用于密码哈希。@rdr:哈希的目的通常是防止有权访问数据库的黑客窃取密码。@rdr加盐可防止rainbow表发挥作用。(简而言之,如果
password
散列到
12345
,那么攻击者只需检查被盗数据库中的散列
12345
,并在不使用salt时立即知道密码