php 在 MYSQL 数据库中存储密码的最佳方式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14798275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to store passwords in MYSQL database
提问by Jeyaganesh
Yes I know storing passwords in plain text is not advised.Is there a best and easy way to store passwords so that the application remains secure ??
是的,我知道不建议以纯文本形式存储密码。是否有最好且简单的方法来存储密码,以便应用程序保持安全?
回答by C1D
First off, md5 and sha1 have been proven to be vulnerable to collision attacks and can be rainbow tabled easily (when they see if you hash is the same in their database of common passwords).
首先,md5 和 sha1 已被证明容易受到碰撞攻击,并且可以很容易地进行彩虹表(当他们查看您的常用密码数据库中的哈希值是否相同时)。
There are currently two things that are secure enough for passwords that you can use.
目前有两件事对于您可以使用的密码来说足够安全。
The first is sha512. sha512 is a sub-version of SHA2. SHA2 has not yet been proven to be vulnerable to collision attacks and sha512 will generate a 512-bit hash. Here is an example of how to use sha512:
第一个是sha512。sha512 是 SHA2 的子版本。SHA2 尚未被证明容易受到碰撞攻击,sha512 将生成 512 位哈希。以下是如何使用 sha512 的示例:
<?php
hash('sha512',$password);
The other option is called bcrypt. bcrypt is famous for its secure hashes. It's probably the most secure one out there and most customizable one too.
另一个选项称为 bcrypt。bcrypt 以其安全的哈希值而闻名。它可能是最安全的,也是最可定制的。
Before you want to start using bcrypt you need to check if your sever has it enabled, Enter this code:
在开始使用 bcrypt 之前,您需要检查您的服务器是否启用了它,输入以下代码:
<?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
echo "CRYPT_BLOWFISH is enabled!";
}else {
echo "CRYPT_BLOWFISH is not available";
}
If it returns that it is enabled then the next step is easy, All you need to do to bcrypt a password is (note: for more customizability you need to see this How do you use bcrypt for hashing passwords in PHP?):
如果它返回它已启用,那么下一步就很简单了,你需要做的就是 bcrypt 密码(注意:为了更多的可定制性,你需要看到这个How do you use bcrypt for hashing password in PHP?):
crypt($password, $salt);
A salt is usually a random string that you add at the end of all your passwords when you hash them. Using a salt means if someone gets your database, they can not check the hashes for common passwords. Checking the database is called using a rainbow table. You should always use a salt when hashing!
盐通常是一个随机字符串,当你对它们进行散列时,你会在所有密码的末尾添加它。使用盐意味着如果有人获取了您的数据库,他们将无法检查常用密码的哈希值。使用彩虹表调用检查数据库。散列时你应该总是使用盐!
Here are my proofs for the SHA1 and MD5 collision attack vulnerabilities:
http://www.schneier.com/blog/archives/2012/10/when_will_we_se.html, http://eprint.iacr.org/2010/413.pdf,
http://people.csail.mit.edu/yiqun/SHA1AttackProceedingVersion.pdf,
http://conf.isi.qut.edu.au/auscert/proceedings/2006/gauravaram06collision.pdfand
Understanding sha-1 collision weakness
以下是我对 SHA1 和 MD5 碰撞攻击漏洞的证明:
http: //www.schneier.com/blog/archives/2012/10/when_will_we_se.html,http: //eprint.iacr.org/2010/413.pdf,
http://people.csail.mit.edu/yiqun/SHA1AttackProceedingVersion.pdf,
http://conf.isi.qut.edu.au/auscert/proceedings/2006/gauravaram06collision.pdf和
了解 sha-1 碰撞弱点
回答by ba0708
Hashing algorithms such as sha1 and md5 are not suitable for password storing. They are designed to be very efficient. This means that brute forcing is very fast. Even if a hacker obtains a copy of your hashed passwords, it is pretty fast to brute force it. If you use a salt, it makes rainbow tables less effective, but does nothing against brute force. Using a slower algorithm makes brute force ineffective. For instance, the bcrypt algorithm can be made as slow as you wish (just change the work factor), and it uses salts internally to protect against rainbow tables. I would go with such an approach or similar (e.g. scrypt or PBKDF2) if I were you.
sha1 和 md5 等哈希算法不适合密码存储。它们的设计非常高效。这意味着暴力破解非常快。即使黑客获得了您的散列密码的副本,暴力破解它的速度也非常快。如果你使用盐,它会降低彩虹表的效果,但对蛮力无济于事。使用较慢的算法会使蛮力无效。例如,bcrypt 算法可以按您的意愿变慢(只需更改工作系数),并且它在内部使用盐来防止彩虹表。如果我是你,我会采用这种方法或类似方法(例如 scrypt 或 PBKDF2)。
回答by Evaldas Dzimanavicius
Passwords in the database should be stored encrypted. One way encryption (hashing) is recommended, such as SHA2, SHA2, WHIRLPOOL, bcrypt DELETED: MD5 or SHA1. (those are older, vulnerable
数据库中的密码应加密存储。建议使用一种加密方式(散列),例如 SHA2、SHA2、WHIRLPOOL、bcrypt DELETED:MD5 或 SHA1。(那些年龄较大,易受伤害的
In addition to that you can use additional per-user generated random string - 'salt':
除此之外,您还可以使用额外的每个用户生成的随机字符串 - 'salt':
$salt = MD5($this->createSalt());
$Password = SHA2($postData['Password'] . $salt);
createSalt()in this case is a function that generates a string from random characters.
createSalt()在这种情况下是一个从随机字符生成字符串的函数。
EDIT: or if you want more security, you can even add 2 salts: $salt1 . $pass . $salt2
编辑:或者如果您想要更高的安全性,您甚至可以添加 2 个盐: $salt1 。$通过。$盐2
Another security measure you can take is user inactivation: after 5 (or any other number) incorrect login attempts user is blocked for x minutes (15 mins lets say). It should minimize success of brute force attacks.
您可以采取的另一种安全措施是用户停用:在 5 次(或任何其他次数)错误登录尝试后,用户将被阻止 x 分钟(可以说是 15 分钟)。它应该最大限度地减少暴力攻击的成功。
回答by William N
Store a unique salt for the user (generated from username + email for example), and store a password. On login, get the salt from database and hash salt + password.
Use bcrypt to hash the passwords.
为用户存储一个唯一的盐(例如从用户名 + 电子邮件生成),并存储一个密码。登录时,从数据库中获取盐并散列盐 + 密码。
使用 bcrypt 散列密码。
回答by Nimrod007
best to use crypt for password storing in DB
最好使用 crypt 将密码存储在数据库中
example code :
示例代码:
$crypted_pass = crypt($password);
//$pass_from_login is the user entered password
//$crypted_pass is the encryption
if(crypt($pass_from_login,$crypted_pass)) == $crypted_pass)
{
echo("hello user!")
}
documentation :
文档:
回答by Bogdan
You should use one way encryption (which is a way to encrypt a value so that is very hard to revers it). I'm not familiar with MySQL, but a quick search shows that it has a password() function that does exactly this kind of encryption. In the DB you will store the encrypted value and when the user wants to authenticate you take the password he provided, you encrypt it using the same algorithm/function and then you check that the value is the same with the password stored in the database for that user. This assumes that the communication between the browser and your server is secure, namely that you use https.
您应该使用单向加密(这是一种加密值的方法,因此很难逆转它)。我不熟悉 MySQL,但快速搜索显示它有一个 password() 函数,可以进行这种加密。在数据库中,您将存储加密的值,当用户想要验证您提供的密码时,您使用相同的算法/函数对其进行加密,然后检查该值是否与存储在数据库中的密码相同那个用户。这假设浏览器和您的服务器之间的通信是安全的,即您使用 https。

