有人告诉我,你不应该将用户密码存储在数据库中,但是如果我不能保存他们的密码,我怎么能对用户进行身份验证?
最近的新闻中有几篇报道说,像 LinkedIn 这样的备受瞩目的网站已经被泄露,我不认为这样一个备受瞩目的网站会存储纯文本密码,所以会假设它们是加密的。
免责声明:我最初发布了this on Quora,但觉得答案更适合 Stack Overflow。
用于存储和检查用户密码而不实际保留密码的方法是将用户输入与存储的哈希进行比较。
什么是哈希?
哈希是通过一种算法传递可变长度(小密码,大密码,二进制文件等)的数据的过程,该算法将其作为一组固定长度的哈希值返回。哈希只能以一种方式工作。由几个 Mb 组成的 *.img 文件可以与密码完全相同地进行哈希处理。(实际上,通常的做法是在大文件上使用哈希来检查它们的完整性,而不是在大文件上使用哈希来下载。
使用哈希进行身份验证是如何工作的?
当用户注册时,他提供了一个密码,例如p123
,然后将其哈希(通过任何可用的哈希算法:sha1,sha256 等,在这种情况下为 md5)值32250170a0dca92d53ec9624f336ca24
,该值存储在数据库中。每次尝试登录时,系统都会实时对您的密码进行哈希处理,并将其与存储的哈希值进行比较,如果匹配,则可以尝试
如果两个哈希值相同怎么办?用户可以使用不同的通行证登录吗?
他可以!这称为碰撞。假设在虚构的哈希算法中,值p123
将产生哈希ec9624
,而值p321
将产生完全相同的哈希,该哈希算法将被。当发现冲突时,常见的算法 md5 和 sha1(使用的 LinkedIn)都被了。被并不一定意味着它不安全。
如何利用碰撞?
如果您可以生成哈希,则与用户密码生成的哈希相同,您可以将该站点标识为用户。
彩虹表攻击。
破解者很快就明白,一旦他们捕获了哈希密码表,就不可能逐个利用密码,因此他们设计了一个新的攻击向量。他们将生成存在的每个密码(aaa,aab,aac,aad 等),并将所有哈希存储在数据库中。然后,他们只需要使用所有按顺序生成的哈希(亚秒查询)在数据库中搜索被盗的哈希,即可获得。
拯救盐(以及 LinkedIn 失败的地方!)
安全性是由破解者破解密码所需的时间以及更改密码的频率来定义的。使用彩虹表,安全性下降得非常快,因此业界提出了盐。如果每个密码都有独特的扭曲怎么办?那是盐!对于每个注册的用户,您都会生成一个随机字符串,例如 3 个字符(业界建议使用 16 个字符-https://stackoverflow.com/a/18419..。)。然后将用户的密码与随机字符串连接起来。
pword - salt - sha1 hash
qwerty - 123 - 5cec175b165e3d5e62c9e13ce848ef6feac81bff
qwerty - 321 - b8b92ab870c50ce5fc59571dc0c77f9a4a90323c
qazwsx - abc - c6aec64efe2a25c6bc35aeea2aafb2e86ac96a0c
qazwsx - cba - 31e42c24f71dc5a453b2635e6ec57eadf03090fd
正如你所看到的,完全相同的密码,给定不同的盐值,产生完全不同的哈希值。这就是盐的目的,也是 LinkedIn 失败的原因。请注意,在桌子上,你只会存储哈希和盐!永远不要密码!
拿到 LinkedIn 哈希值的人做的第一件事就是对哈希值进行排序,看看是否有匹配项(这是因为多个用户拥有相同的密码-真可惜!)这些用户是第一个删除的用户。如果通行证表被加盐了……这些都不会发生,他们将需要大量的时间(和计算机资源)来破解每个密码。这将使 LinkedIn 有足够的时间来执行新的策略
希望答案的技术方面提供了有关身份验证如何工作(或应该工作)的见解。
真的很喜欢,当有人问这个问题时,因为这个人想做得更好。只知道几个要点,即使是知名网站也可以避免很多麻烦。
最近我写了一个关于Hashing pwords的教程,它使用了一种希望简单易懂的语言。它允许使用 SQL 注入,解释了盐和胡椒的用法,并指出需要缓慢的密钥派生函数。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(46条)