简体   繁体   English

如何正确存储密码*?

[英]How to store passwords *correctly*?

An article that I stumbled upon here in SO provided links to other articles which in turn provided links to even more articles etc. 我在SO中偶然发现的一篇文章提供了与其他文章的链接, 这些文章反过来提供了更多 文章的链接等。

And in the end I was left completely stumped - so what is the best way to store passwords in the DB? 最后我完全被遗忘了 - 那么在DB中存储密码的最佳方法是什么? From what I can put together you should: 从我可以放在一起你应该:

  • Use a long (at least 128 fully random bits) salt, which is stored in plaintext next to the password; 使用长(至少128个完全随机位)盐,它以密码旁边的明文存储;
  • Use several iterations of SHA-256 (or even greater SHA level) on the salted password. 在salted密码上使用SHA-256的几次迭代(甚至更高的SHA级别)。

But... the more I read about cryptography the more I understand that I don't really understand anything, and that things I had thought to be true for years are actually are flat out wrong. 但是......我读到的关于密码学的内容越多,我就越了解我并不真正理解任何东西,而且我多年来认为真实的东西实际上是错误的。 Are there any experts on the subject here? 这里有专家吗?

Added: Seems that some people are missing the point. 补充:似乎有些人忽视了这一点。 I repeat the last link given above. 我重复上面给出的最后一个链接。 That should clarify my concerns. 这应该澄清我的担忧。

https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2007/july/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/ https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2007/july/enough-with-the-rainbow-tables-what-you-need-to-know-about-安全密码的方案/

You got it right. 你做对了。 Only two suggestions: 只有两个建议:

  1. If one day SHA1 becomes too weak and you want to use something else, it is impossible to unhash the old passwords and rehash them with the new scheme. 如果有一天SHA1变得太弱并且您想要使用其他东西,则无法取消旧密码并将其重新与新方案重新使用。 For this reason, I suggest that attached to each password a "version" number that tells you what scheme you used (salt length, which hash, how many times). 出于这个原因,我建议在每个密码上附加一个“版本”号,告诉你你使用了什么方案(盐长度,哪个哈希,多少次)。 If one day you need to switch from SHA to something stronger, you can create new-style passwords while still having old-style passwords in the database and still tell them apart. 如果有一天你需要从SHA切换到更强的东西,你可以创建新式密码,同时在数据库中仍然使用旧式密码,并仍然分开它们。 Migrating users to the new scheme will be easier. 将用户迁移到新方案将更容易。

  2. Passwords still go from user to system without encryption. 密码仍然从用户到系统而没有加密。 Look at SRP if that's a problem. 如果这是一个问题,请查看SRP SRP is so new that you should be a little paranoid about implementing it, but so far it looks promising. SRP是如此新颖,你应该对实现它有点偏执,但到目前为止看起来很有希望。

Edit: Turns out bcrypt beat me to it on idea number 1. The stored info is (cost, salt, hash), where cost is how many times the hashing has been done. 编辑:结果是bcrypt在想法编号1上击败了我。存储的信息是(成本,盐,哈希),其中成本是散列完成的次数。 Looks like bcrypt did something right. 看起来像bcrypt做对了。 Increasing the number of times that you hash can be done without user intervention. 无需用户干预即可增加散列次数。

In truth it depends on what the passwords are for. 实际上,这取决于密码的用途。 You should take storing any password with care, but sometimes much greater care is needed than others. 您应该小心存储任何密码,但有时需要比其他人更加小心。 As a general rule all passwords should be hashed and each password should have a unique salt. 作为一般规则,应对所有密码进行哈希处理,并且每个密码都应具有唯一的盐。

Really, salts don't need to be that complex, even small ones can cause a real nightmare for crackers trying to gain entry into the system. 实际上,盐并不需要那么复杂,即使很小的盐也会导致试图进入系统的破解者真正的噩梦。 They are added to a password to prevent the use of Rainbow tables to hack multiple account's passwords. 它们被添加到密码中以防止使用Rainbow表来破解多个帐户的密码。 I wouldn't add a single letter of the alphabet to a password and call it a salt, but you don't need to make it a unique guid which is encrypted somewhere else in the database either. 我不会在密码中添加单个字母的字母,并将其称为盐,但您不需要将其设置为在数据库中的其他位置加密的唯一guid。

One other thing concerning salts. 关于盐的另一件事。 The key to making a password + salt work when hashing is the complexity of the combination of the two. 散列时使密码+盐工作的关键是两者结合的复杂性。 If you have a 12 character password and add a 1 character salt to it, the salt doesn't do much, but cracking the password is still a monumental feat. 如果你有一个12个字符的密码并添加1个字符的盐,盐不会做太多,但破解密码仍然是一个巨大的壮举。 The reverse is also true. 反之亦然。

Use: 使用:

  1. Hashed password storage 哈希密码存储
  2. A 128+ bit user-level salt, random, regenerated (ie you make new salts when you make new password hashes, you don't persistently keep the same salt for a given user) 一个128位以上的用户级盐,随机,重新生成(即,当您创建新密码哈希时,您创建新盐,您不会持续为给定用户保留相同的盐)
  3. A strong, computationally expensive hashing method 一种强大的,计算上昂贵的散列方法
  4. Methodology that is somewhat different (hash algorithm, how many hashing iterations you use, what order the salts are concatenated in, something ) from both any 'standard implementation guides' like these and from any other password storage implementation you've written 方法有点不同(哈希算法,你使用多少哈希迭代,连接盐的顺序, 某些东西 )来自这些的任何“标准实现指南”以及你编写的任何其他密码存储实现

我认为没有额外的密码需要密码,juste确保有一个盐和一个复杂的;)我个人使用SHA-1结合2个盐关键短语。

The length of the salt doesnt really matter, as long as it is unique to a user. 盐的长度并不重要,只要它对用户来说是独一无二的。 The reason for a salt is so that a given generated attempt at a hash match is only useful for a single row of your users table in the DB. salt的原因是,对哈希匹配的给定生成尝试仅对DB中的用户表的单行有用。

Simply said, use a cryptographically secure hash algorithm and some salt for the passwords, that should be good enough for 99.99% of all use cases. 简单地说,使用加密安全哈希算法和密码的一些盐,这应该足够99.99%的所有用例。 The weak link will be the code that checks the password as well as the password input. 弱链接将是检查密码和密码输入的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM