在 MySQL 表中存储用户密码的最佳 PHP 散列方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6472667/
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 PHP hashing method for storing user passwords in a MySQL table?
提问by iamandrus
I've been reading Stack Overflow questions for about 15 minutes now and every single one seems to contradict the previous one I read. Bcrypt, SHA1, MD5, and so on. I currently MD5 my passwords, but I want to make my database more secure in case of a breach.
我已经阅读 Stack Overflow 问题大约 15 分钟了,每一个问题似乎都与我阅读的前一个相矛盾。Bcrypt、SHA1、MD5 等。我目前对我的密码进行 MD5,但我想让我的数据库更安全,以防万一。
I know this has been asked a million times, but I can't seem to find a decent answer anywhere else.
我知道这已经被问了一百万次,但我似乎在其他任何地方都找不到合适的答案。
Thanks.
谢谢。
采纳答案by George Cummins
The reason you see contradictory answers is because there is no right one. You should use the most secure method that your application can support. More secure = more overhead.
你看到相互矛盾的答案是因为没有正确的答案。您应该使用您的应用程序可以支持的最安全的方法。更安全 = 更多开销。
MD5has been broken and cracked.
MD5已损坏并破解。
According to this article, SHA1 is broken. However it has not yet been cracked.
根据这篇文章,SHA1 已损坏。然而它还没有被破解。
bcrypt has not (to the best of my knowledge) been found to be broken.
bcrypt 没有被发现(据我所知)被破坏。
Given enough CPU cycles, any hashing or encryption algorithm can eventually be circumvented. Your decision should balance the security of your data with the performance of your application.
给定足够的 CPU 周期,最终可以绕过任何散列或加密算法。您的决定应在数据安全性与应用程序性能之间取得平衡。
Given those caveats, bcrypt is the defacto standard at this time. It is designed for strength, not speed, and is not known to be broken. For an index of information about bcrypt, see the bcrypt article on Wikipedia.
鉴于这些警告,bcrypt 目前是事实上的标准。它专为力量而不是速度而设计,并且不会被破坏。有关 bcrypt 的信息索引,请参阅Wikipedia 上的bcrypt 文章。
回答by ceejayoz
I'd go with bcrypt. It drastically reduces the ability to generate rainbow tables.
我会和 bcrypt 一起去。它大大降低了生成彩虹表的能力。
http://codahale.com/how-to-safely-store-a-password/
http://codahale.com/how-to-safely-store-a-password/
It's important to note that salts are useless for preventing dictionary attacks or brute force attacks. You can use huge salts or many salts or hand-harvested, shade-grown, organic Himalayan pink salt. It doesn't affect how fast an attacker can try a candidate password, given the hash and the salt from your database.
需要注意的是,盐对于防止字典攻击或蛮力攻击是无用的。您可以使用大量盐或多种盐,或手工采摘、阴凉生长的有机喜马拉雅粉红盐。考虑到数据库中的哈希值和盐值,它不会影响攻击者尝试候选密码的速度。
回答by Teo.sk
First of all, MD5 isn't a very good option nowadays. If an attacker would get to your database, and get the MD5 hashes, it is almost certain that he will be also able to crack them. MD5 hashes of weak passwords can be cracked even bruteforce by a casual computer.
首先,MD5 现在不是一个很好的选择。如果攻击者进入您的数据库并获得 MD5 哈希值,几乎可以肯定他也能够破解它们。弱密码的 MD5 哈希值甚至可以通过普通计算机暴力破解。
You should google some articles about salting your hashes, and use that method combined with a stronger hashing algorithm (at least SHA1), and maybe repeat the process few times.
你应该在谷歌上搜索一些关于对你的散列加盐的文章,并使用该方法结合更强大的散列算法(至少是 SHA1),并可能重复该过程几次。
I am not going to write about salting, as many articles have been already written about it, and also here on Stack Overflow you can find many good discussions about the problem. E.g. Why do salts make dictionary attacks 'impossible'?or How does password salt help against a rainbow table attack?
我不打算写关于加盐的文章,因为已经写了很多关于它的文章,而且在 Stack Overflow 上你可以找到很多关于这个问题的很好的讨论。例如, 为什么盐会使字典攻击“不可能”?或 密码盐如何帮助抵御彩虹表攻击?
回答by Jan Willem
When a user registers, create a random salt
using, for example, the following function:
当用户注册时,salt
使用例如以下函数创建随机数:
$bytes = 50;
$salt = base64_encode(openssl_random_pseudo_bytes($bytes));
Store this in a database table. The best is to store it in an external database. After this, create a random code and store it together with your salt into the external database. Than store the random code in your users table and it will almost be impossible for an attacker to find your salt.
将其存储在数据库表中。最好是将其存储在外部数据库中。在此之后,创建一个随机代码并将其与您的盐一起存储到外部数据库中。与将随机代码存储在您的用户表中相比,攻击者几乎不可能找到您的盐。
After this, store your password in, for example, this way:
在此之后,例如,以这种方式存储您的密码:
$password_to_store_in_mysql = hash('sha512', $salt . $user_password);
When a user logs in, get the salt out of the external database en check if the salt and the password match.
当用户登录时,从外部数据库中取出盐并检查盐和密码是否匹配。
回答by FinalForm
Use MD5, SHA1 or whatever encryption you want with a SALT
.
使用 MD5、SHA1 或任何你想要的加密SALT
。
For this example, I'm just going to use MD5 for explanation sake.
对于这个例子,我只是为了解释而使用 MD5。
So user chooses a password, store that in $password for instance.
因此用户选择一个密码,例如将其存储在 $password 中。
Now create a salt that's specific to your application.
现在创建一个特定于您的应用程序的盐。
$salt = 'my very own salt'; // or maybe make a random string for your salt
Then do
然后做
$more_difficult_password = md5($salt . $password);
This way people can't use dictionary attacks by just googling your MD5 string if it ever got compromised somehow.
这样人们就不能通过谷歌搜索你的 MD5 字符串来使用字典攻击,如果它以某种方式受到损害。
回答by GitsD
You can use secret key of your website and particular salt of every user with your password. Your secret key of your website should be saved in your database and then fetch it and use.
您可以使用您网站的密钥和每个用户的特定盐与您的密码。您网站的密钥应该保存在您的数据库中,然后获取并使用。
The combination becomes.
组合成为。
$secret = "your key from database";
$salt = "user salt";// make it randomly
$password = $_POST['password'];
$new_pass = md5($secret.$salt.$password);
Now this combinations will store in database.
现在这个组合将存储在数据库中。
At the time of login, use again this combination to match.
登录时,再次使用该组合进行匹配。
I think it can help more to secure your application.
我认为它可以帮助更多地保护您的应用程序。
Cheers..!!
干杯..!!