Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
452 views
in Technique[技术] by (71.8m points)

php - 保护PHP密码的哈希和盐值(Secure hash and salt for PHP passwords)

It is currently said that MD5 is partially unsafe. (当前据说MD5部分不安全。) Taking this into consideration, I'd like to know which mechanism to use for password protection. (考虑到这一点,我想知道使用哪种机制进行密码保护。)

This question, Is “double hashing” a password less secure than just hashing it once? (这个问题, “双重哈希”密码是否比仅哈希一次密码安全?) suggests that hashing multiple times may be a good idea, whereas How to implement password protection for individual files? (建议多次散列可能是一个好主意,而如何对单个文件实施密码保护?) suggests using salt. (建议使用盐。)

I'm using PHP. (我正在使用PHP。) I want a safe and fast password encryption system. (我想要一个安全,快速的密码加密系统。) Hashing a password a million times may be safer, but also slower. (将密码哈希一百万次可能更安全,但也更慢。) How to achieve a good balance between speed and safety? (如何在速度和安全性之间取得良好的平衡?) Also, I'd prefer the result to have a constant number of characters. (另外,我希望结果具有恒定数量的字符。)

  1. The hashing mechanism must be available in PHP (哈希机制必须在PHP中可用)
  2. It must be safe (必须安全)
  3. It can use salt (in this case, are all salts equally good? Is there any way to generate good salts?) (它可以使用盐(在这种情况下,所有盐都一样好吗?是否有任何方法可以生成优质盐?))

Also, should I store two fields in the database (one using MD5 and another one using SHA, for example)? (另外,我是否应该在数据库中存储两个字段(例如,一个使用MD5,另一个使用SHA)?) Would it make it safer or unsafer? (它会使它更安全或更不安全吗?)

In case I wasn't clear enough, I want to know which hashing function(s) to use and how to pick a good salt in order to have a safe and fast password protection mechanism. (如果我不够清楚,我想知道要使用哪个哈希函数以及如何选择合适的盐,以便拥有安全,快速的密码保护机制。)

Related questions that don't quite cover my question: (尚未完全涵盖我的问题的相关问题:)

What's the difference between SHA and MD5 in PHP (PHP中的SHA和MD5有什么区别)
Simple Password Encryption (简单密码加密)
Secure methods of storing keys, passwords for asp.net (安全的asp.net密钥,密码存储方法)
How would you implement salted passwords in Tomcat 5.5 (您将如何在Tomcat 5.5中实现盐腌密码)

  ask by luiscubal translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

DISCLAIMER : This answer was written in 2008. (免责声明 :该答案写于2008年。)

Since then, PHP has given us password_hash and password_verify and, since their introduction, they are the recommended password hashing & checking method. (从那时起,PHP就给了我们password_hashpassword_verify并且自从引入以来,它们就是推荐的密码哈希和检查方法。)

The theory of the answer is still a good read though. (答案的理论仍然是一个很好的阅读。)

TL;DR (TL; DR)

Don'ts (不要)

  • Don't limit what characters users can enter for passwords. (不要限制用户可以输入哪些字符作为密码。) Only idiots do this. (只有白痴这样做。)
  • Don't limit the length of a password. (不要限制密码的长度。) If your users want a sentence with supercalifragilisticexpialidocious in it, don't prevent them from using it. (如果您的用户想要一个句子,其中包含supercalifragilisticexpialidocious,请不要阻止他们使用它。)
  • Don't strip or escape HTML and special characters in the password. (不要在密码中剥离或转义HTML和特殊字符。)
  • Never store your user's password in plain-text. (切勿以纯文本形式存储用户密码。)
  • Never email a password to your user except when they have lost theirs, and you sent a temporary one. (除非用户忘记了密码, 否则不要通过电子邮件将密码发送给您的用户,而是您发送了一个临时密码)
  • Never, ever log passwords in any manner. (永远不要以任何方式记录密码。)
  • Never hash passwords with SHA1 or MD5 or even SHA256! (切勿使用SHA1或MD5甚至SHA256哈希密码!) Modern crackers can exceed 60 and 180 billion hashes/second (respectively). (现代饼干可以分别超过60和1800亿个哈希/秒。)
  • Don't mix bcrypt and with the raw output of hash() , either use hex output or base64_encode it. (请勿将bcrypt与hash()的原始输出混合使用,请使用十六进制输出或base64_encode对其进行编码。) (This applies to any input that may have a rogue \0 in it, which can seriously weaken security.) ((这适用于其中可能包含流氓\0任何输入,这会严重削弱安全性。))

Dos (多斯)

  • Use scrypt when you can; (尽可能使用scrypt;) bcrypt if you cannot. (如果不能,请使用bcrypt。)
  • Use PBKDF2 if you cannot use either bcrypt or scrypt, with SHA2 hashes. (如果不能使用带有SHA2散列的bcrypt或scrypt,请使用PBKDF2。)
  • Reset everyone's passwords when the database is compromised. (数据库受到威胁时,请重置每个人的密码。)
  • Implement a reasonable 8-10 character minimum length, plus require at least 1 upper case letter, 1 lower case letter, a number, and a symbol. (实施合理的8-10个字符的最小长度,再加上至少1个大写字母,1个小写字母,一个数字和一个符号。) This will improve the entropy of the password, in turn making it harder to crack. (这将改善密码的熵,从而使其更难以破解。) (See the "What makes a good password?" section for some debate.) ((有关一些辩论,请参见“什么才是好的密码?”部分。))

Why hash passwords anyway? (为什么仍要哈希密码?)

The objective behind hashing passwords is simple: preventing malicious access to user accounts by compromising the database. (哈希密码的目的很简单:通过破坏数据库来防止对用户帐户的恶意访问。) So the goal of password hashing is to deter a hacker or cracker by costing them too much time or money to calculate the plain-text passwords. (因此,密码哈希的目的是通过花费大量时间或金钱来计算纯文本密码,从而阻止黑客或黑客。) And time/cost are the best deterrents in your arsenal. (时间/成本是您武器库中最好的威慑力量。)

Another reason that you want a good, robust hash on a user accounts is to give you enough time to change all the passwords in the system. (您想要对用户帐户进行良好而可靠的哈希处理的另一个原因是,给您足够的时间来更改系统中的所有密码。) If your database is compromised you will need enough time to at least lock the system down, if not change every password in the database. (如果您的数据库遭到破坏,您将需要足够的时间至少锁定系统,如果不更改数据库中的每个密码。)

Jeremiah Grossman, CTO of Whitehat Security, stated on White Hat Security blog after a recent password recovery that required brute-force breaking of his password protection: (Whitehat Security的首席技术官Jeremiah Grossman在最近的密码恢复后要求在蛮力破解他的密码保护之后, 在White Hat Security博客上说。)

Interestingly, in living out this nightmare, I learned A LOT I didn't know about password cracking, storage, and complexity. (有趣的是,在摆脱这场噩梦的过程中,我学到了很多我不知道的有关密码破解,存储和复杂性的信息。) I've come to appreciate why password storage is ever so much more important than password complexity. (我已经明白了为什么密码存储比密码复杂性重要得多。) If you don't know how your password is stored, then all you really can depend upon is complexity. (如果您不知道密码的存储方式,那么您真正可以依靠的仅仅是复杂性。) This might be common knowledge to password and crypto pros, but for the average InfoSec or Web Security expert, I highly doubt it. (这可能是密码和加密专家的常识,但是对于一般的InfoSec或Web安全专家而言,我对此表示高度怀疑。)

(Emphasis mine.) ((强调我的。))

What makes a good password anyway? (无论如何,什么才是好的密码?)

Entropy . ( 。) (Not that I fully subscribe to Randall's viewpoint.) ((并不是我完全赞同兰德尔的观点。))

In short, entropy is how much variation is within the password. (简而言之,熵就是密码中的变化量。) When a password is only lowercase roman letters, that's only 26 characters. (当密码仅为小写罗马字母时,则只有26个字符。) That isn't much variation. (差异不大。) Alpha-numeric passwords are better, with 36 characters. (字母数字密码最好使用36个字符。) But allowing upper and lower case, with symbols, is roughly 96 characters. (但是允许带符号的大写和小写字母约为96个字符。) That's a lot better than just letters. (这比仅字母要好得多。) One problem is, to make our passwords memorable we insert patterns—which reduces entropy. (一个问题是,为了使我们的密码令人难忘,我们插入了模式,从而减少了熵。) Oops! (糟糕!)

Password entropy is approximated easily. (密码熵近似容易。) Using the full range of ascii characters (roughly 96 typeable characters) yields an entropy of 6.6 per character, which at 8 characters for a password is still too low (52.679 bits of entropy) for future security. (使用全部范围的ascii字符(大约96个可键入字符),每个字符的熵为6.6,而对于8个字符的密码,它的熵仍然太低(熵的52.679位),对于将来的安全性而言太低了。) But the good news is: longer passwords, and passwords with unicode characters, really increase the entropy of a password and make it harder to crack. (但好消息是:更长的密码以及带有unicode字符的密码,确实增加了密码的熵并使其难以破解。)

There's a longer discussion of password entropy on the Crypto StackExchange site. (在Crypto StackExchange站点上,关于密码熵的讨论已经很长时间了。) A good Google search will also turn up a lot of results. (良好的Google搜索也会带来很多结果。)

In the comments I talked with @popnoodles, who pointed out that enforcing a password policy of X length with X many letters, numbers, symbols, etc, can actually reduce entropy by making the password scheme more predictable. (在我与@popnoodles交谈的评论中,他指出强制 X长度为X的密码策略包含X个字母,数字,符号等,实际上可以通过使密码方案更可预测来减少熵。) I do agree. (我同意。) Randomess, as truly random as possible, is always the safest but least memorable solution. (随机性,尽可能真正地随机性,始终是最安全但最难忘的解决方案。)

So far as I've been able to tell, making the world's best password is a Catch-22. (据我所知,制作世界上最好的密码是Catch-22。) Either its not memorable, too predictable, too short, too many unicode characters (hard to type on a Windows/Mobile device), too long, etc. No password is truly good enough for our purposes, so we must protect them as though they were in Fort Knox. (它不是令人难忘,太可预测,太短,太多的Unicode字符(在Windows /移动设备上很难键入),太长的时间等等。没有密码确实足以满足我们的目的,因此我们必须像保护密码一样保护它们在诺克斯堡。)

Best practices (最佳实践)

Bcrypt and scrypt are the current best practices. (Bcrypt和scrypt是当前的最佳实践。) Scrypt will be better than bcrypt in time, but it hasn't seen adoption as a standard by Linux/Unix or by webservers, and hasn't had in-depth reviews of its algorithm posted yet. (Scrypt</a


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...