我被告知您不应将用户密码存储在数据库中,但如果我无法保存密码,如何验证用户身份?只是加密它们足以保证它们安全吗?
最近有一些关于受到妥协的高调网站的新闻,如LinkedIn,我不认为这么高调的网站会存储纯文本密码,所以会假设它们是加密的。
答案 0 :(得分:6)
免责声明:我最初发布this on Quora但感觉答案更适合Stack Overflow。
用于存储和检查用户密码而不实际保存密码的方法是将用户输入与存储的哈希值进行比较。
什么是哈希?
散列是通过算法传递可变长度数据(小密码,大密码,二进制文件等)的过程,该算法将其作为一组称为散列值的固定长度返回。哈希只有一种方式。由几个Mb组成的* .img文件可以与密码完全相同。 (实际上,在大型文件上使用哈希来检查它们的完整性是一种常见的做法;假设您使用bittorrent下载文件,当它完成时,软件会对其进行哈希处理,并将您所拥有的哈希值与您应该使用的哈希值进行比较。有,如果匹配,下载没有损坏)。
使用哈希的auth如何工作?
当用户注册他提供密码时,请说pass123
然后经过哈希(通过任何可用的哈希算法:sha1,sha256等,在这种情况下为md5)到值32250170a0dca92d53ec9624f336ca24
并且该值存储在数据库中。每次尝试登录系统时都会实时哈希密码并将其与存储的哈希值进行比较,如果匹配,您就可以了。您可以在此处尝试在线md5哈希:http://md5-hash-online.waraxe.us/
如果两个哈希相同怎么办?用户可以使用不同的密码登录吗?
他可以!这被称为碰撞。假设在虚构的哈希算法中,值pass123
将产生哈希ec9624
,值pass321
将产生完全相同的哈希,哈希算法将被破坏。两种常见的算法md5和sha1(LinkedIn使用的算法)都被破坏,因为已经找到了碰撞。被打破并不一定意味着它不安全。
如何利用冲突?
如果您可以生成哈希,这与用户密码生成的哈希相同,您可以以该用户身份识别该站点。
彩虹桌攻击。
Crackers很快就明白,一旦他们捕获了一个哈希密码表,就不可能逐个利用密码,因此他们设计了一个新的攻击媒介。它们将生成存在的每个密码(aaa,aab,aac,aad等等)并将所有哈希值存储在数据库中。然后他们只需要使用所有顺序生成的哈希值(亚秒级查询)搜索数据库中被盗的哈希值并获取相应的密码。
盐救援(以及LinkedIn失败的地方!)
安全性的定义是破解者破解密码所需的时间以及更改密码的频率。随着彩虹表安全下降真的很快,所以业界提出了盐。如果每个密码都有独特的变化怎么办?那是盐!对于每个注册的用户,您生成一个随机字符串,比如说3个字符(业界推荐16个字符 - https://stackoverflow.com/a/18419..。)。然后将用户密码与随机字符串连接起来。
password - salt - sha1 hash
qwerty - 123 - 5cec175b165e3d5e62c9e13ce848ef6feac81bff
qwerty - 321 - b8b92ab870c50ce5fc59571dc0c77f9a4a90323c
qazwsx - abc - c6aec64efe2a25c6bc35aeea2aafb2e86ac96a0c
qazwsx - cba - 31e42c24f71dc5a453b2635e6ec57eadf03090fd
正如您可以看到完全相同的密码,给定不同的盐值,生成完全不同的哈希值。这就是盐的目的以及为什么LinkedIn失败了。请注意,在表格中,您只会存储哈希和盐!从来没有密码!
那些得到LinkedIn哈希的人的第一件事就是对哈希进行排序,看看是否有匹配(因为有多个用户拥有相同的密码 - 对他们感到羞耻!)这些用户是第一个下降。如果传递表被腌制......没有一个会发生这种情况,他们将需要一些难以忍受的时间(和计算机资源)来破解每一个密码。这将给LinkedIn带来足够的时间来实施新的密码策略。
希望答案的技术方面能够深入了解身份验证的工作原理(或应该如何工作)。
答案 1 :(得分:1)
真的很喜欢,当有人提出这个问题时,因为有人想要做得更好。只知道几个重点,即使是知名网站也可以避免很多麻烦。
最近我写了一篇关于Hashing passwords的教程,它使用了一种希望简单易懂的语言。它允许使用SQL注入,解释盐和胡椒的使用,并指出需要缓慢的密钥派生函数。