SHA1 与 md5 与 SHA256:哪个用于 PHP 登录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2235158/
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
SHA1 vs md5 vs SHA256: which to use for a PHP login?
提问by Tony Stark
I'm making a php login, and I'm trying to decide whether to use SHA1 or Md5, or SHA256 which I read about in another stackoverflow article. Are any of them more secure than others? For SHA1/256, do I still use a salt?
我正在使用 php 登录,我正在尝试决定是使用 SHA1 还是 Md5,或者我在另一篇 stackoverflow 文章中读到的 SHA256。他们中的任何一个比其他人更安全吗?对于 SHA1/256,我还使用盐吗?
Also, is this a secure way to store the password as a hash in mysql?
另外,这是将密码作为哈希存储在 mysql 中的安全方式吗?
function createSalt()
{
$string = md5(uniqid(rand(), true));
return substr($string, 0, 3);
}
$salt = createSalt();
$hash = sha1($salt . $hash);
采纳答案by Johannes Gorset
Neither. You should use bcrypt. The hashes you mention are all optimized to be quick and easy on hardware, and so cracking them share the same qualities. If you have no other choice, at least be sure to use a long salt and re-hash multiple times.
两者都不。你应该使用bcrypt. 您提到的哈希都经过优化,可以在硬件上快速轻松地进行破解,因此破解它们具有相同的品质。如果你别无选择,至少一定要使用长盐并多次重新哈希。
Using bcrypt in PHP 5.5+
在 PHP 5.5+ 中使用 bcrypt
PHP 5.5 offers new functions for password hashing. This is the recommend approach for password storage in modern web applications.
PHP 5.5 提供了新的密码散列函数。这是现代 Web 应用程序中密码存储的推荐方法。
// Creating a hash
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// If you omit the ['cost' => 12] part, it will default to 10
// Verifying the password against the stored hash
if (password_verify($password, $hash)) {
// Success! Log the user in here.
}
If you're using an older version of PHP you really should upgrade, but until you do you can use password_compatto expose this API.
如果您使用的是旧版本的 PHP,您确实应该升级,但在升级之前您可以使用password_compat来公开此 API。
Also, please let password_hash()generate the salt for you. It uses a CSPRNG.
另外,请让我们password_hash()为您生成盐。它使用CSPRNG。
Two caveats of bcrypt
bcrypt 的两个注意事项
- Bcrypt will silently truncate any password longer than 72 characters.
- Bcrypt will truncate after any
NULcharacters.
- Bcrypt 将静默截断任何超过 72 个字符的密码。
- Bcrypt 将在任何
NUL字符后截断。
(Proof of Conceptfor both caveats here.)
(此处两个警告的概念证明。)
You might be tempted to resolve the first caveat by pre-hashing your passwords before running them through bcrypt, but doing so can cause your application to run headfirst into the second.
您可能想通过在通过 bcrypt 运行密码之前预先散列密码来解决第一个警告,但这样做可能会导致您的应用程序首先运行到第二个。
Instead of writing your own scheme, use an existing library written and/or evaluated by security experts.
使用由安全专家编写和/或评估的现有库,而不是编写自己的方案。
Zend\Crypt(part of Zend Framework) offersBcryptShaPasswordLockis similar toBcryptShabut it also encrypts the bcrypt hashes with an authenticated encryption library.
Zend\Crypt(Zend 框架的一部分)提供BcryptShaPasswordLock类似于BcryptSha但它也使用经过身份验证的加密库加密 bcrypt 哈希。
TL;DR- Use bcrypt.
TL;DR-使用 bcrypt。
回答by Roger Johnson
I think using md5 or sha256 or any hash optimized for speed is perfectly fine and am very curious to hear any rebuttle other users might have. Here are my reasons
我认为使用 md5 或 sha256 或任何针对速度优化的哈希都非常好,并且很想听到其他用户可能有的任何反驳。这是我的理由
If you allow users to use weak passwords such as God, love, war, peace then no matter the encryption you will still be allowing the user to type in the password not the hash and these passwords are often used first, thus this is NOTgoing to have anything to do with encryption.
If your not using SSL or do not have a certificate then attackers listening to the traffic will be able to pull the password and any attempts at encrypting with javascript or the like is client side and easily cracked and overcome. Again this is NOTgoing to have anything to do with data encryption on server side.
Brute force attacks will take advantage weak passwords and again because you allow the user to enter the data if you do not have the login limitation of 3 or even a little more then the problem will again NOThave anything to do with data encryption.
If your database becomes compromised then most likely everything has been compromised including your hashing techniques no matter how cryptic you've made it. Again this could be a disgruntled employee XSS attack or sql injection or some other attack that has nothing to do with your password encryption.
如果您允许用户使用诸如上帝、爱、War、和平之类的弱密码,那么无论加密如何,您仍然会允许用户输入密码而不是哈希,并且这些密码通常首先使用,因此这不会发生与加密有任何关系。
如果您不使用 SSL 或没有证书,那么侦听流量的攻击者将能够提取密码,并且任何使用 javascript 等加密的尝试都是客户端,并且很容易被破解和克服。再次,这是不打算有任何瓜葛与服务器端的数据加密。
蛮力攻击将利用弱口令,并再次因为你允许用户输入数据,如果你不具备的3登录限制,甚至更多一点,那么问题将再次不具有任何与数据加密。
如果您的数据库遭到破坏,那么很可能一切都已受到损害,包括您的散列技术,无论您做得多么神秘。同样,这可能是心怀不满的员工 XSS 攻击或 sql 注入或其他一些与您的密码加密无关的攻击。
I do believe you should still encrypt but the only thing I can see the encryption does is prevent people that already have or somehow gained access to the database from just reading out loud the password. If it is someone unauthorized to on the database then you have bigger issues to worry about that's why Sony got took because they thought an encrypted password protected everything including credit card numbers all it does is protect that one field that's it.
我确实相信您仍然应该加密,但我能看到的唯一加密功能是防止已经或以某种方式获得数据库访问权限的人只是大声读出密码。如果有人未经授权访问数据库,那么您需要担心更大的问题,这就是索尼被盗的原因,因为他们认为加密密码可以保护包括信用卡号在内的所有内容,它所做的只是保护一个字段。
The only pure benefit I can see to complex encryptions of passwords in a database is to delay employees or other people that have access to the database from just reading out the passwords. So if it's a small project or something I wouldn't worry to much about security on the server side instead I would worry more about securing anything a client might send to the server such as sql injection, XSS attacks or the plethora of other ways you could be compromised. If someone disagrees I look forward to reading a way that a super encrypted password is a must from the client side.
对于数据库中密码的复杂加密,我能看到的唯一纯粹的好处是延迟员工或其他有权访问数据库的人读取密码。因此,如果它是一个小项目或其他东西,我不会太担心服务器端的安全性,相反,我会更担心保护客户端可能发送到服务器的任何内容,例如 sql 注入、XSS 攻击或过多的其他方式。可能会受到损害。如果有人不同意,我期待从客户端阅读一种必须使用超级加密密码的方法。
The reason I wanted to try and make this clear is because too often people believe an encrypted password means they don't have to worry about it being compromised and they quit worrying about securing the website.
我想尝试澄清这一点的原因是因为人们常常相信加密的密码意味着他们不必担心它会被泄露,他们不再担心网站的安全。
回答by LexLythius
As Johannes Gorset pointed out, the post by Thomas Ptacek from Matasano Securityexplains why simple, general-purpose hashing functions such as MD5, SHA1, SHA256 and SHA512 are poor password hashing choices.
正如 Johannes Gorset 所指出的,来自 Matasano Security 的 Thomas Ptacek 的帖子解释了为什么简单的通用散列函数(例如 MD5、SHA1、SHA256 和 SHA512)是糟糕的密码散列选择。
Why? They are too fast--you can calculate at least 1,000,000 MD5 hashes a second per core with a modern computer, so brute force is feasible against most passwords people use. And that's much less than a GPU-based cracking server cluster!
为什么?它们太快了——您可以使用现代计算机每秒计算每个内核至少 1,000,000 个 MD5 哈希值,因此对于人们使用的大多数密码,暴力破解是可行的。这比基于 GPU 的破解服务器集群要少得多!
Salting without key stretching only means that you cannot precompute the rainbow table, you need to build it ad hoc for that specific salt. But it won't really make things that much harder.
没有键拉伸的加盐仅意味着您不能预先计算彩虹表,您需要为特定的盐特别构建它。但它不会真的让事情变得更难。
User @Will says:
用户@Will 说:
Everyone is talking about this like they can be hacked over the internet. As already stated, limiting attempts makes it impossible to crack a password over the Internet and has nothing to do with the hash.
每个人都在谈论这个,就像他们可以通过互联网被黑客入侵一样。如前所述,限制尝试使得无法通过 Internet 破解密码并且与散列无关。
They don't need to. Apparently, in the case of LinkedInthey used the common SQL injection vulnerabilityto get the login DB table and cracked millions of passwords offline.
他们不需要。显然,在LinkedIn的案例中,他们使用了常见的SQL注入漏洞来获取登录数据库表,并离线破解了数百万个密码。
Then he goes back to the offline attack scenario:
然后他又回到了离线攻击场景:
The security really comes into play when the entire database is compromised and a hacker can then perform 100 million password attempts per second against the md5 hash. SHA512 is about 10,000 times slower.
当整个数据库遭到破坏并且黑客每秒可以针对 md5 哈希执行 1 亿次密码尝试时,安全性才真正发挥作用。SHA512 大约慢 10,000 倍。
No, SHA512is not 10000 times slower than MD5--it only takes about twice as much. Crypt/SHA512, on the other hand, is a very different beast that, like its BCrypt counterpart, performs key stretching, producing a very different hash with a random salt built-in and will take anything between 500 and 999999 times as much to compute (stretching is tunable).
不,SHA512并不比 MD5 慢 10000 倍——它只需要大约两倍。另一方面,Crypt/SHA512是一个非常不同的野兽,就像它的 BCrypt 对应物一样,执行密钥拉伸,生成一个非常不同的哈希,内置随机盐,并且需要 500 到 999999 倍的计算量(拉伸是可调的)。
SHA512 => aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Crypt/SHA512 => $rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21
So the choice for PHP is either Crypt/Blowfish (BCrypt), Crypt/SHA256 or Crypt/SHA512. Or at least Crypt/MD5 (PHK). See www.php.net/manual/en/function.crypt.php
所以 PHP 的选择是 Crypt/Blowfish (BCrypt)、Crypt/SHA256 或 Crypt/SHA512。或者至少是 Crypt/MD5 (PHK)。见www.php.net/manual/en/function.crypt.php
回答by Kyle Rozendo
Use SHA256. It is not perfect, as SHA512would be ideal for a fast hash, but out of the options, its the definite choice. As per any hashing technology, be sure to salt the hash for added security.
使用SHA256. 它并不完美,因为它是SHA512快速散列的理想选择,但在选项之外,它是明确的选择。根据任何散列技术,请务必对散列加盐以增加安全性。
As an added note, FRKT, please show me where someone can easily crack a salted SHA256 hash? I am truly very interested to see this.
作为补充说明,FRKT,请告诉我哪里有人可以轻松破解盐渍 SHA256 哈希?我真的很感兴趣看到这个。
Important Edit:
重要编辑:
Moving forward please use bcryptas a hardened hash. More information can be found here.
继续前进,请bcrypt用作强化哈希。可以在此处找到更多信息。
Edit on Salting:
编辑盐渍:
Use a random number, or random byte stream etc. You can use the unique field of the record in your database as the salt too, this way the salt is different per user.
使用随机数或随机字节流等。您也可以使用数据库中记录的唯一字段作为盐,这样每个用户的盐是不同的。
回答by Dennis Bellinger
What people seem to be missing is that if the hacker has access to the database he probably also has access to the php file that hashes the password and can likely just modify that to send him all the successful user name password combos. If he doesn't have access to the web directory he could always just pick a password hash it, and write that into the database. In other words the hash algorithm doesn't really matter as much as system security, and limiting login attempts also if you don't use SSL then the attacker can just listen in on the connection to get the information. Unless you need the algorithm to take a long time to compute (for your own purposes) then SHA-256 or SHA-512 with a user specific saltshould be enough.
人们似乎缺少的是,如果黑客可以访问数据库,他可能也可以访问散列密码的 php 文件,并且可能只需修改它即可将所有成功的用户名密码组合发送给他。如果他无法访问网络目录,他总是可以选择一个密码散列,然后将其写入数据库。换句话说,哈希算法并不像系统安全那么重要,并且如果您不使用 SSL,那么限制登录尝试也是如此,那么攻击者可以监听连接以获取信息。除非您需要算法花费很长时间来计算(出于您自己的目的),否则带有用户特定盐的 SHA-256 或 SHA-512就足够了。
As an added security measure set up a script (bash, batch, python, etc) or program and give it an obscure name and have it check and see if login.php has changed (check date/time stamp) and send you an email if it has. Also should probably log all attempts at login with admin rights and log all failed attempts to log into the database and have the logs emailed to you.
作为一项额外的安全措施,设置一个脚本(bash、批处理、python 等)或程序,并给它一个不起眼的名字,让它检查 login.php 是否已更改(检查日期/时间戳)并向您发送电子邮件如果有。还应该记录所有以管理员权限登录的尝试,并记录所有登录数据库的失败尝试,并将日志通过电子邮件发送给您。
回答by Will
Everyone is talking about this like they can be hacked over the internet. As already stated, limiting attempts makes it impossible to crack a password over the Internet and has nothing to do with the hash.
每个人都在谈论这个,就像他们可以通过互联网被黑客入侵一样。如前所述,限制尝试使得无法通过 Internet 破解密码并且与散列无关。
The salt is a must, but the complexity or multiple salts doesn't even matter. Any salt alone stops the attacker from using a premade rainbow table. A unique salt per user stops the attacker from creating a new rainbow table to use against your entire user base.
盐是必须的,但复杂性或多种盐甚至无关紧要。任何盐都可以阻止攻击者使用预制的彩虹桌。每个用户唯一的盐可以阻止攻击者创建一个新的彩虹表来用于整个用户群。
The security really comes into play when the entire database is compromised and a hacker can then perform 100 million password attempts per second against the md5 hash. SHA512 is about 10,000 times slower. A complex password with today's power could still take 100 years to bruteforce with md5 and would take 10,000 times as long with SHA512. The salts don't stop a bruteforce at all as they always have to be known, which if the attacker downloaded your database, he probably was in your system anyway.
当整个数据库遭到破坏并且黑客每秒可以针对 md5 哈希执行 1 亿次密码尝试时,安全性才真正发挥作用。SHA512 大约慢 10,000 倍。具有当今强大功能的复杂密码仍然需要 100 年才能使用 md5 进行暴力破解,而使用 SHA512 则需要 10,000 倍的时间。盐根本不能阻止暴力破解,因为它们总是必须被知道的,如果攻击者下载了您的数据库,他可能无论如何都在您的系统中。
回答by Erwan Legrand
Use argon2i. The argon2password hashing function has won the Password Hashing Competition.
使用argon2i。该argon2密码散列函数先后荣获中的密码哈希比赛。
Other reasonable choices, if using argon2is not available, are scrypt, bcryptand PBKDF2. Wikipedia has pages for these functions:
如果使用argon2不可用,其他合理的选择是scrypt、bcrypt和PBKDF2。维基百科有这些功能的页面:
- https://en.wikipedia.org/wiki/Argon2
- http://en.wikipedia.org/wiki/Scrypt
- http://en.wikipedia.org/wiki/Bcrypt
- http://en.wikipedia.org/wiki/PBKDF2
- https://en.wikipedia.org/wiki/Argon2
- http://en.wikipedia.org/wiki/Scrypt
- http://en.wikipedia.org/wiki/Bcrypt
- http://en.wikipedia.org/wiki/PBKDF2
MD5, SHA1 and SHA256 are message digests, not password-hashing functions. They are not suitable for this purpose.
MD5、SHA1 和 SHA256 是消息摘要,而不是密码散列函数。它们不适合此目的。
Switching from MD5 to SHA1 or SHA512 will not improve the security of the construction so much. Computing a SHA256 or SHA512 hash is very fast. An attacker with common hardware could still try tens of millions (with a single CPU) or even billions (with a single GPU) of hashes per second. Good password hashing functions include a work factor to slow down dictionary attacks.
从 MD5 切换到 SHA1 或 SHA512 不会提高构造的安全性。计算 SHA256 或 SHA512 哈希非常快。具有通用硬件的攻击者仍然可以每秒尝试数千万(使用单个 CPU)甚至数十亿(使用单个 GPU)的哈希值。良好的密码散列函数包括减缓字典攻击的工作因素。
Here is a suggestion for PHP programmers: read the PHP FAQthen use password_hash().
这里有一个给 PHP 程序员的建议:阅读PHP FAQ然后使用password_hash()。
回答by Brad Jensen
MD5 is bad because of collision problems - two different passwords possibly generating the same md-5.
由于冲突问题,MD5 很糟糕 - 两个不同的密码可能会生成相同的 md-5。
Sha-1 would be plenty secure for this. The reason you store the salted sha-1 version of the password is so that you the swerver do not keep the user's apassword on file, that they may be using with other people's servers. Otherwise, what difference does it make?
Sha-1 对此非常安全。您存储密码的加盐 sha-1 版本的原因是,您的服务器不会将用户的密码保存在文件中,因为他们可能正在与其他人的服务器一起使用。否则,有什么区别?
If the hacker steals your entire unencrypted database some how, the only thing a hashed salted password does is prevent him from impersonating the user for future signons - the hacker already has the data.
如果黑客以某种方式窃取了您的整个未加密数据库,那么散列加盐密码唯一能做的就是防止他冒充用户进行未来登录——黑客已经拥有数据。
What good does it do the attacker to have the hashed value, if what your user inputs is a plain password?
如果您的用户输入的是普通密码,那么攻击者拥有散列值有什么好处?
And even if the hacker with future technology could generate a million sha-1 keys a second for a brute force attack, would your server handle a million logons a second for the hacker to test his keys? That's if you are letting the hacker try to logon with the salted sha-1 instead of a password like a normal logon.
即使拥有未来技术的黑客可以每秒生成 100 万个 sha-1 密钥进行强力攻击,您的服务器是否会每秒处理 100 万次登录以供黑客测试他的密钥?那是如果您让黑客尝试使用加盐的 sha-1 而不是像普通登录那样的密码登录。
The best bet is to limit bad logon attempts to some reasonable number - 25 for example, and then time the user out for a minute or two. And if the cumulative bady logon attempts hits 250 within 24 hours, shut the account access down and email the owner.
最好的办法是将错误登录尝试限制在某个合理的数字内 - 例如 25,然后让用户超时一两分钟。如果在 24 小时内累积的 bady 登录尝试达到 250,请关闭帐户访问权限并向所有者发送电子邮件。
回答by Biswajit Karmakar
回答by Lars Gross
An md5 encryption is one of the worst, because you have to turn the code and it is already decrypted. I would recommend you the SHA256. I'm programming a bit longer and have had a good experience. Below would also be an encryption.
md5 加密是最糟糕的加密之一,因为您必须转动代码并且它已经被解密。我会向您推荐 SHA256。我的编程时间有点长,并且有很好的经验。下面也将是一个加密。
password_hash() example using Argon2i
<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
The above example will output something similar to:
Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0


