现代网站如何在不实际存储的情况下检查您的密码?

Fra*_*kie 4 security passwords hash hashtable

我被告知您不应该将用户密码存储在数据库中,但如果我无法保存密码,如何验证用户身份?只是加密它们足以保证它们的安全吗?

最近新闻中出现了几个受到妥协的高调网站的故事,比如LinkedIn,我不认为这么高调的网站会存储明文密码,所以会假设它们是加密的.

Fra*_*kie 6

免责声明:我最初在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使用的算法)都被破坏,因为已经找到了碰撞.被打破并不一定意味着它不安全.

你如何利用碰撞?

如果您可以生成散列,则与用户密码生成的散列相同,您可以将该散列标识为用户.

彩虹表攻击.

克拉克斯很快就明白,一旦他们捕获了一个哈希密码表,就不可能逐个利用密码,因此他们设计了一个新的攻击媒介.它们将生成存在的每个密码(aaa,aab,aac,aad等等)并将所有哈希值存储在数据库中.然后,他们只需要使用所有顺序生成的哈希值(亚秒级查询)搜索数据库中的被盗哈希值并获取相应的密码.

盐救援(以及LinkedIn失败的地方!)

安全性由破解者破解密码所需的时间以及更改密码的频率来定义.随着彩虹表安全下降真的很快,所以业界提出了盐.如果每个密码都有独特的变化怎么办?那是盐!对于每个注册的用户,您生成一个随机字符串,比如3个字符(业界推荐16个字符 - /sf/answers/1289361/ ..).然后,将用户的密码与随机字符串连接起来.

password - salt - sha1 hash  
qwerty   - 123  - 5cec175b165e3d5e62c9e13ce848ef6feac81bff  
qwerty   - 321  - b8b92ab870c50ce5fc59571dc0c77f9a4a90323c  
qazwsx   - abc  - c6aec64efe2a25c6bc35aeea2aafb2e86ac96a0c  
qazwsx   - cba  - 31e42c24f71dc5a453b2635e6ec57eadf03090fd  
Run Code Online (Sandbox Code Playgroud)

正如您可以看到完全相同的密码,给定不同的盐值,生成完全不同的哈希值.这就是盐的目的以及为什么LinkedIn失败了.请注意,在表格中,您只会存储哈希和盐!从来没有密码!

第一件事就是得到了他们在LinkedIn哈希上做的第一件事就是对哈希进行排序,看看是否有匹配(因为有多个用户拥有相同的密码 - 对他们感到羞耻!)这些用户是第一个掉线的人.如果传递表被腌制......没有一个会发生这种情况,他们将需要一些难以忍受的时间(和计算机资源)来破解每一个密码.这将给LinkedIn带来足够的时间来实施新的密码策略.

希望答案的技术方面能够深入了解身份验证的工作原理(或应该如何工作).

  • 散列算法发生冲突的事实并没有使其"破碎".如果您没有将密码的大小限制到足够低的限制,那么将存在更多可能的密码而不是哈希值(任何哈希算法几乎都是这种情况).良好的散列算法可以尽可能地减少冲突,并尝试"类似"的输入值不会产生相同的散列.另外,散列的大小与冲突概率成反比(使用非可怕的算法).哈希值越多越好. (4认同)
  • -1此答案包含几个过时的概念,不应用作密码安全性的参考.可能这部分是因为它试图回答一个过于宽泛的问题,并且需要更长,更长的答案才能完成. (4认同)
  • 写得不好,没有提到强化等基本概念,而关于碰撞的部分则极具误导性.碰撞将允许您创建一个您知道两个不同有效密码的用户.不是一个非常有用的攻击.查找与其他用户的哈希匹配的密码称为预映像,即使使用MD5,这仍然非常昂贵. (3认同)
  • @CodesInChaos的意思是"非常昂贵"是2 ^ 123.4的攻击,这将需要比宇宙的年龄更长的完成.请注意,目前对MD5的可行攻击是选择前缀攻击,在攻击散列密码时基本上没用.这并不是说MD5是用于密码保护的好算法(也不是任何通用散列函数,如SHA-*系列).没有提到像bcrypt这样的专用密码散列函数(以及为什么应该使用它们)是我对这个答案最大的问题. (3认同)