SHA1 vs md5 vs SHA256:哪个用于 PHP 登录?
Posted
技术标签:
【中文标题】SHA1 vs md5 vs SHA256:哪个用于 PHP 登录?【英文标题】:SHA1 vs md5 vs SHA256: which to use for a PHP login? 【发布时间】:2011-01-15 03:55:14 【问题描述】:我正在进行 php 登录,我正在尝试决定是使用 SHA1 还是 Md5,还是使用我在另一篇 *** 文章中读到的 SHA256。他们中的任何一个都比其他人更安全吗?对于 SHA1/256,我还使用盐吗?
另外,这是一种将密码作为哈希值存储在 mysql 中的安全方式吗?
function createSalt()
$string = md5(uniqid(rand(), true));
return substr($string, 0, 3);
$salt = createSalt();
$hash = sha1($salt . $hash);
【问题讨论】:
见***.com/questions/1592608/… 另请参阅this answer 并阅读有关密码哈希的部分。 【参考方案1】:两者都没有。你应该使用bcrypt
。您提到的哈希都经过优化,可以在硬件上快速简便,因此破解它们具有相同的品质。如果您别无选择,至少一定要使用长盐并重新哈希多次。
在 PHP 5.5+ 中使用 bcrypt
PHP 5.5 提供new functions for password hashing。这是现代 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.
如果您使用的是旧版本的 PHP you really should upgrade,但在您这样做之前,您可以使用 password_compat 公开此 API。
另外,请让password_hash()
为您生成盐。它使用CSPRNG。
bcrypt 的两个注意事项
-
Bcrypt 将静默截断任何长度超过 72 个字符的密码。
Bcrypt 将在任何
NUL
字符后截断。
(这里的两个警告都是Proof of Concept。)
您可能想通过pre-hashing your passwords before running them through bcrypt 解决第一个警告,但这样做可能会导致您的应用程序先运行到第二个。
不要编写自己的方案,而是使用由安全专家编写和/或评估的现有库。
Zend\Crypt
(Zend 框架的一部分)提供 BcryptSha
PasswordLock
类似于 BcryptSha
,但它也使用 authenticated encryption library 加密 bcrypt 哈希。
TL;DR - Use bcrypt.
【讨论】:
另外,我对此很陌生:sha1、sha256 和 md5 是您所指的所有“哈希”吗? 是的。我指的是 SHA1、SHA256 和 MD5 以及一系列针对速度进行了优化的其他哈希值。您不想使用针对速度优化的哈希来保护密码。讨论原因的好文章很多,我特别喜欢这篇:chargen.matasano.com/chargen/2007/9/7/… 自 PHP 5.3 起包含在“crypt”函数中。如果您有较早的版本,我会研究“phpass”框架以获得下一个最好的东西。 @Stanislav Palatnik SHA512 是一个不错的选择。不要误会我的意思;我并不是说拉伸和加盐的 SHA512 哈希是不安全的。它是安全的。即便如此,事实仍然是 bcrypt 更安全,所以我认为没有理由不使用它。 @Cypher:bcrypt
被设计为缓慢,以同样缓慢地破解。【参考方案2】:
我认为使用 md5 或 sha256 或任何针对速度优化的哈希都非常好,我很想听到其他用户可能有的任何反驳。这是我的理由
如果您允许用户使用弱密码,例如上帝、爱、战争、和平,那么无论加密如何,您仍将允许用户输入密码而不是哈希值,并且这些密码通常首先使用,因此这不会与加密有任何关系。
1234563同样,这不会与服务器端的数据加密有任何关系。暴力攻击将再次利用弱密码,因为您允许用户输入数据,如果您没有登录限制 3 甚至更多,那么问题将再次出现 NOT 与数据加密有关。
如果您的数据库受到威胁,那么很可能所有内容都已受到威胁,包括您的散列技术,无论您所做的多么神秘。同样,这可能是心怀不满的员工 XSS 攻击或 sql 注入或其他与您的密码加密无关的攻击。
我确实认为您仍然应该加密,但我能看到加密所做的唯一事情是防止已经拥有或以某种方式获得数据库访问权限的人只是大声读出密码。如果有人未经授权访问数据库,那么您需要担心更大的问题,这就是索尼被带走的原因,因为他们认为加密密码可以保护包括信用卡号码在内的所有内容,它所做的只是保护那个字段。
我可以看到对数据库中的密码进行复杂加密的唯一纯粹好处是延迟员工或其他有权访问数据库的人仅仅读出密码。因此,如果它是一个小项目或其他东西,我不会太担心服务器端的安全性,而是会更担心保护客户端可能发送到服务器的任何东西,例如 sql 注入、XSS 攻击或过多的其他方式可能会受到损害。如果有人不同意,我期待阅读客户端必须使用超级加密密码的方式。
我想尝试说明这一点的原因是,人们常常认为加密密码意味着他们不必担心密码被泄露,并且他们不再担心网站的安全问题。
【讨论】:
说得好。网络安全应优先于散列技术,它们不仅可以保存您的数据,还可以使服务器防御做好准备。 这真的是误传。当然,在数据库中安全地散列密码并不能提高应用程序级别或数据库级别的安全性。为了安全,这不是万能的。您想在数据库中安全地散列用户密码有两个原因;首先,客户使用他们的密码信任您,他们可能会或可能不会在其他网站上使用该密码,因此您要确保即使您的数据库遭到破坏,也无法恢复,其次,您希望在安全的情况下免除责任违反。我不知道任何临时诉讼,但泄露密码会让你的公司看起来很糟糕。 这是个坏建议。如果有人窃取了您的数据库并获取了您所有的散列密码,即使他们还破坏了您数据库的其他部分,防止他们破解密码和登录仍然很重要。 (例如,考虑一个银行网站。)速度优化算法使攻击者能够针对被盗的哈希测试许多候选人,直到他们找到匹配项。像 bcrypt 和 scrypt 这样的算法,即使他们知道你使用什么算法,也使得测试候选人的哈希值变得缓慢和昂贵。因此,如果有人窃取了哈希值,它们会提供更好的保护。 “如果您的数据库遭到入侵,那么很可能一切都已被入侵,包括您的散列技术,无论您所做的多么神秘。”这就是 为什么 bcrypt 如此重要的原因。使用 bcrypt,是否有人拥有哈希并不重要。使用像 SHA1/MD5 这样的快速哈希算法,它确实如此。 我认为你们中的一些人缺少的一点是,当所有其他数据都是明文时,密码是否 1000% 安全并不重要。例如,如果整个数据库遭到破坏,那么黑客现在拥有所有明文信用卡号。是的,许多人在不同的网站上使用相同的密码,但他们已经被告知不要这样做,所以这不再是我们的问题。如果数据库本身包含敏感信息,并且它的危害是一个问题,那么加密整个数据库,只要你认为有必要。【参考方案3】:正如 Johannes Gorset 所指出的,the post by Thomas Ptacek from Matasano Security 解释了为什么 MD5、SHA1、SHA256 和 SHA512 等简单的通用散列函数是糟糕的密码散列选择。
为什么?它们太快了——你可以用现代计算机计算每个内核每秒至少 1,000,000 个 MD5 哈希值,因此对于人们使用的大多数密码来说,蛮力是可行的。这比基于 GPU 的破解服务器集群要少得多!
没有键拉伸的加盐仅意味着您无法预先计算彩虹表,您需要为特定的盐临时构建它。但这不会让事情变得那么困难。
用户@Will 说:
每个人都在谈论这个,就像他们可能被黑客入侵一样 互联网。如前所述,限制尝试使得不可能 通过互联网破解密码,与密码无关 哈希。
他们不需要。显然,在the case of LinkedIn中,他们使用了常见的SQL injection vulnerability来获取登录数据库表并离线破解了数百万个密码。
然后他回到离线攻击场景:
当整个数据库都处于安全状态时,安全性才真正发挥作用 被攻破,然后黑客可以执行 1 亿个密码 每秒针对 md5 哈希的尝试次数。 SHA512约10000次 慢一点。
不,SHA512 并不比 MD5 慢 10000 倍——它只需要大约两倍。另一方面,Crypt/SHA512 是一个非常不同的野兽,就像它的 BCrypt 对应物一样,它执行key stretching,产生一个非常不同的哈希值,内置随机盐,并且可以在500 和 999999 倍的计算量(拉伸是可调的)。
SHA512 => aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Crypt/SHA512 => $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21
所以 PHP 的选择是 Crypt/Blowfish (BCrypt)、Crypt/SHA256 或 Crypt/SHA512。或者至少是 Crypt/MD5 (PHK)。见www.php.net/manual/en/function.crypt.php
【讨论】:
简单的密码散列很好,由防火墙来保证服务器的安全.. “防火墙”是指一个反应性防火墙,它可以阻止/减慢蛮力(人类可以只打字那么快)..这场比赛毫无意义.. ..“如果某个黑客闯入并且现在拥有一切怎么办”(面对桌面)-如果黑客进入您的服务器-它就结束了。密码被破解主要是因为它们太简单了,或者软件开发人员太懒了,不能像网络罪犯一样思考。 @argon 请再读一遍。散列密码的全部目的是当您的登录数据库受到威胁(并且在某些时候会),您不会立即泄露所有用户的密码,这些密码最常被用户重用跨不同的站点——否则输入后的简单延迟就可以了。而“如果他们进入您的服务器,游戏结束”是一个有争议的问题,因为他们不需要进入您的服务器进入。黑客最常使用的漏洞是 SQL 注入(参见 Linkedin 案例),然后他们对哈希进行暴力破解。这就是你需要加盐和拉伸的原因。 如果安全要求真的如此严格,那么将密码存储在别处可能是个好主意。有很多方法可以保护您的数据(和源代码)-对于“如果/何时” ... ..-但是将密码散列到“无数位”仅与以下安全性一样安全:密码创建者/访客系统、数据传输和服务服务器硬件的人员。 .. 话虽这么说:我并不是说散列是无用的,但我是说如果你的解决方案只是更复杂的散列,那么关于量子计算机,我担心它在不久的将来不会起作用。 递归散列会增加任何黑客攻击的工作/成本。迭代次数越多,破解就越难,因此甚至可以使用像 SHA256 这样的快速哈希。迭代必须是随机的并且可以公开。password_hash()
显示哈希本身的成本。
@VictorStoddard 是的,您可以推出自己的散列方案并提供可调密钥延伸。但是,您为什么想要这样做,而不是使用已经存在的、经过更彻底审查的、专家为此目的创建并提供的算法?【参考方案4】:
使用SHA256
。它并不完美,因为SHA512
是快速散列的理想选择,但在选项之外,它是绝对的选择。根据任何散列技术,一定要对散列加盐以增加安全性。
作为补充说明,FRKT,请告诉我在哪里可以轻松破解加盐的 SHA256 哈希?看到这个我真的很感兴趣。
重要编辑:
继续前进,请使用bcrypt
作为强化哈希。更多信息可以found here。
盐渍编辑:
使用随机数或随机字节流等。您也可以使用数据库中记录的唯一字段作为盐,这样每个用户的盐是不同的。
【讨论】:
但它们针对速度进行了优化,这意味着它们可以进行暴力破解。 事实仍然如此,这是为了保护密码。通过使用带盐的哈希,然后在网站上添加 3 次尝试限制,您可以大大减慢黑客的尝试(甚至是蛮力)。使用任何纯加密,您现在遇到另一个问题 - 保护密钥。如果找到密钥,您的整个数据库就会受到威胁(如果没有添加盐)。然而,散列,你永远不会从系统中得到原始密码,它应该是这样的。 如前所述,MD 和 SHA 系列的问题在于它们针对速度进行了优化。随着计算的发展,这种性质的哈希不可避免地会变得越来越不安全。 随着计算的发展,Anything 变得越来越糟糕/不安全/等等。当 SHA512 等被黑客入侵时,将会有更安全的算法可用。无论如何,这就是计算的本质。 用php制作盐的好方法是什么?有示例代码吗?我想我不应该只选择“长颈鹿”之类的东西【参考方案5】:人们似乎缺少的是,如果黑客可以访问数据库,他可能还可以访问对密码进行哈希处理的 php 文件,并且可能只需修改该文件以向他发送所有成功的用户名密码组合。如果他无权访问网络目录,他总是可以选择一个密码散列,并将其写入数据库。换句话说,哈希算法并不像系统安全那么重要,并且如果您不使用 SSL 并且限制登录尝试,那么攻击者可以只监听连接以获取信息。除非您需要算法花费很长时间来计算(出于您自己的目的),否则 SHA-256 或 SHA-512 以及用户特定的盐就足够了。
作为一项附加的安全措施,设置一个脚本(bash、batch、python 等)或程序,并给它一个不起眼的名称,并让它检查 login.php 是否已更改(检查日期/时间戳)并发送如果有的话,给你一封电子邮件。还应该记录所有以管理员权限登录的尝试,并记录所有登录数据库失败的尝试,并将日志通过电子邮件发送给您。
【讨论】:
“人们似乎缺少的是,如果黑客可以访问数据库,他可能还可以访问散列密码的 php 文件......” 这不是真的。最常见的漏洞之一是 SQL 注入,它赋予数据库读/写能力,但对 PHP 代码的访问为零。 如果您有权访问代码,那么您可以修改并存储用户以纯文本形式发送的所有密码。所以不,如果代码被泄露,那么游戏结束。【参考方案6】:每个人都在谈论这个,就像他们可以通过互联网被黑客入侵一样。如前所述,限制尝试使得无法通过 Internet 破解密码,并且与哈希无关。
盐是必须的,但复杂性或多种盐甚至都无关紧要。任何盐都可以阻止攻击者使用预制的彩虹表。每个用户唯一的盐可以阻止攻击者创建一个新的彩虹表来针对您的整个用户群。
当整个数据库受到威胁时,安全性才真正发挥作用,然后黑客可以每秒对 md5 哈希执行 1 亿次密码尝试。 SHA512 大约慢了 10,000 倍。具有当今强大功能的复杂密码仍然需要 100 年才能使用 md5 进行暴力破解,而使用 SHA512 则需要 10,000 倍。 salts 根本无法阻止暴力破解,因为它们总是必须知道的,如果攻击者下载了您的数据库,他可能无论如何都在您的系统中。
【讨论】:
【参考方案7】:由于冲突问题,MD5 不好 - 两个不同的密码可能生成相同的 md-5。
Sha-1 对此非常安全。您存储密码的加盐 sha-1 版本的原因是,您的 swerver 不会将用户的密码保存在文件中,因为他们可能会与其他人的服务器一起使用。否则,有什么区别?
如果黑客以某种方式窃取了您的整个未加密数据库,散列加盐密码的唯一作用就是防止他冒充用户进行未来登录 - 黑客已经拥有数据。
如果您的用户输入的是普通密码,那么攻击者拥有哈希值有什么好处?
即使拥有未来技术的黑客可以每秒生成一百万个 sha-1 密钥来进行暴力攻击,您的服务器是否会每秒处理一百万次登录以供黑客测试他的密钥?也就是说,如果您让黑客尝试使用加盐 sha-1 而不是像普通登录那样的密码登录。
最好的办法是将错误的登录尝试限制在某个合理的数字 - 例如 25 次,然后让用户退出一两分钟。如果在 24 小时内累计错误登录尝试达到 250 次,请关闭帐户访问权限并向所有者发送电子邮件。
【讨论】:
即使我使用的是较弱的加密,几乎没有系统可以承受每秒超过 100 万次尝试的暴力攻击。 三次登录失败,您被锁定。期,故事结束。如果黑客碰巧先尝试了“password”、“pa$$word”和“passw0rd”(锁定!),即使是像“1234”这样的超级愚蠢的密码也是安全的。现在,用户如何重新获得访问权限成为您的安全症结所在,而您所做的事情取决于您的用户群规模。 200 个用户?让他们打电话寻求帮助。 这个答案是否对其他人没有意义,还是只有我自己?【参考方案8】:这里是 MD5 和 SHA1 的比较。您可以清楚地了解哪个更好。
【讨论】:
【参考方案9】:使用 argon2i。 argon2 密码哈希函数在密码哈希竞赛中获胜。
如果无法使用 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/PBKDF2MD5、SHA1 和 SHA256 是消息摘要,而不是密码散列函数。它们不适合此目的。
从 MD5 切换到 SHA1 或 SHA512 不会大大提高构造的安全性。计算 SHA256 或 SHA512 哈希非常快。使用普通硬件的攻击者仍然可以每秒尝试数千万次(使用单个 CPU)甚至数十亿次(使用单个 GPU)的哈希值。 良好的密码哈希函数包括减缓字典攻击的工作因素。
这里是给 PHP 程序员的一个建议:阅读PHP FAQ,然后使用password_hash()。
【讨论】:
【参考方案10】:让我们假设下一点:黑客窃取了我们的数据库,包括用户和密码(加密)。黑客使用他们知道的密码创建了一个虚假帐户。
MD5 很弱,因为它简短而流行,而且几乎每个没有密码的散列生成都不会受到字典攻击。但是..
所以,假设我们仍在使用带有 SALT 的 MD5。黑客不知道 SALT,但他们知道特定用户的密码。所以他们可以测试: ?????12345 其中 12345 是知道密码,?????是盐。黑客迟早会猜到 SALT。
但是,如果我们使用 MD5+SALT 并应用了 MD5,则无法恢复信息。但是,我再说一遍,MD5 仍然很短。
例如,假设我的密码是:12345。SALT 是 BILLCLINTON
md5 : 827ccb0eea8a706c4c34a16891f84e7b
md5 哈希:56adb0f19ac0fb50194c312d49b15378
mD5 与 md5 上的哈希:28a03c0bc950decdd9ee362907d1798a 我尝试使用这些在线服务,但我发现没有一个能够破解它。而且它唯一的MD5! (可能就像今天一样,因为我在线生成了 md5,所以它会被破解)
如果你想矫枉过正,那么 SHA256 与盐一起应用两次就绰绰有余了。
tldr MD5(HASH+MD5(password)) = ok 但很短,SHA256 绰绰有余。
【讨论】:
使用带有盐的 MD5 的问题是计算机可以以超快的速度对一个密码进行暴力攻击。 shylor.com/2015/09/14/php-5-5-secure-password-hashing【参考方案11】: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
【讨论】:
以上是关于SHA1 vs md5 vs SHA256:哪个用于 PHP 登录?的主要内容,如果未能解决你的问题,请参考以下文章
用PowerShell的命令行检查文件的校验MD5 SHA1 SHA256
java 用Java生成HMAC MD5 / SHA1 / SHA256等