135

我正在进行 php 登录,我正在尝试决定是使用 SHA1 还是 Md5,还是使用我在另一篇 stackoverflow 文章中读到的 SHA256。他们中的任何一个都比其他人更安全吗?对于 SHA1/256,我还使用盐吗?

另外,这是将密码作为哈希值存储在 mysql 中的安全方法吗?

function createSalt()
{
    $string = md5(uniqid(rand(), true));
    return substr($string, 0, 3);
}

$salt = createSalt();

$hash = sha1($salt . $hash);
4

11 回答 11

112

两者都不。你应该使用bcrypt. 您提到的哈希都经过优化,可以在硬件上快速简便,因此破解它们具有相同的品质。如果您别无选择,至少要确保使用长盐并多次重新哈希。

在 PHP 5.5+ 中使用 bcrypt

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.
}

如果您使用的是旧版本的 PHP ,您确实应该升级,但在您升级之前,您可以使用password_compat来公开此 API。

另外,请让我们password_hash()为您生成盐。它使用CSPRNG

bcrypt 的两个注意事项

  1. Bcrypt 将静默截断任何超过 72 个字符的密码。
  2. Bcrypt 将在任何NUL字符后截断。

(这里的两个警告的概念证明。)

您可能想通过在通过 bcrypt 运行密码之前预先散列密码来解决第一个警告,但这样做可能会导致您的应用程序先运行到第二个。

与其编写自己的方案,不如使用由安全专家编写和/或评估的现有库。

TL;DR -使用 bcrypt

于 2010-02-10T07:48:58.927 回答
22

我认为使用 md5 或 sha256 或任何针对速度优化的哈希都非常好,我很想听到其他用户可能有的任何反驳。这是我的理由

  1. 如果您允许用户使用弱密码,例如上帝、爱、战争、和平,那么无论加密如何,您仍将允许用户输入密码而不是哈希,并且这些密码通常首先使用,因此这是行不通的与加密有任何关系。

  2. 如果您不使用 SSL 或没有证书,那么监听流量的攻击者将能够提取密码,并且任何使用 javascript 等进行加密的尝试都是客户端,并且很容易被破解和克服。同样,这与服务器端的数据加密没有任何关系

  3. 蛮力攻击将再次利用弱密码,因为如果您没有 3 甚至更多的登录限制,您允许用户输入数据,那么问题将再次与数据加密无关。

  4. 如果您的数据库受到威胁,那么很可能所有内容都已受到威胁,包括您的散列技术,无论您所做的多么神秘。同样,这可能是心怀不满的员工 XSS 攻击或 sql 注入或其他与您的密码加密无关的攻击。

我确实相信您仍然应该加密,但我唯一能看到加密所做的就是防止已经拥有或以某种方式获得数据库访问权限的人只是大声读出密码。如果有人未经授权访问数据库,那么您需要担心更大的问题,这就是索尼被带走的原因,因为他们认为加密密码可以保护包括信用卡号在内的所有内容,它所做的只是保护那个字段。

我可以看到对数据库中的密码进行复杂加密的唯一纯粹好处是延迟员工或其他有权访问数据库的人仅仅读出密码。因此,如果它是一个小项目或其他东西,我不会太担心服务器端的安全性,而是会更担心保护客户端可能发送到服务器的任何东西,例如 sql 注入、XSS 攻击或过多的其他方式可能会受到损害。如果有人不同意,我期待阅读客户端必须使用超级加密密码的方式。

我想尝试说明这一点的原因是因为人们常常认为加密密码意味着他们不必担心它会被泄露,并且他们不再担心保护网站。

于 2011-09-24T14:55:39.000 回答
15

正如 Johannes Gorset 所指出的,来自 Matasano Security 的 Thomas Ptacek 的帖子解释了为什么简单的通用散列函数(如 MD5、SHA1、SHA256 和 SHA512)是糟糕的密码散列选择

为什么?它们太快了——你可以用现代计算机计算每个核心每秒至少 1,000,000 个 MD5 哈希值,因此对于人们使用的大多数密码来说,蛮力是可行的。这比基于 GPU 的破解服务器集群要少得多!

没有键拉伸的加盐仅意味着您无法预先计算彩虹表,您需要为特定的盐临时构建它。但它不会真的让事情变得更难。

用户@Will 说:

每个人都在谈论这个,就像他们可以通过互联网被黑客入侵一样。如前所述,限制尝试使得无法通过 Internet 破解密码,并且与哈希无关。

他们不需要。显然,在LinkedIn 的案例中,他们使用常见的SQL 注入漏洞来获取登录数据库表并离线破解数百万个密码。

然后他回到离线攻击场景:

当整个数据库遭到破坏时,安全性才真正发挥作用,然后黑客可以每秒对 md5 哈希执行 1 亿次密码尝试。SHA512 大约慢 10,000 倍。

不,SHA512并不比 MD5 慢 10000 倍——它只需要大约两倍。另一方面,Crypt/SHA512是一种非常不同的野兽,它与 BCrypt 对应物一样,执行密钥拉伸,产生一个非常不同的哈希值,内置随机盐,计算量在 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

于 2010-09-08T18:33:48.040 回答
13

使用SHA256. 它并不完美,SHA512对于快速散列来说是理想的,但在选项之外,它是明确的选择。根据任何散列技术,一定要对散列加盐以增加安全性。

作为补充说明,FRKT,请告诉我在哪里可以轻松破解加盐的 SHA256 哈希?我真的很感兴趣看到这个。

重要编辑:

继续前进,请bcrypt用作硬化哈希。更多信息可以在这里找到


盐渍编辑:

使用随机数或随机字节流等。您也可以使用数据库中记录的唯一字段作为盐,这样每个用户的盐是不同的。

于 2010-02-10T07:58:28.957 回答
4

人们似乎缺少的是,如果黑客可以访问数据库,他可能还可以访问散列密码的 php 文件,并且可能只需修改该文件以向他发送所有成功的用户名密码组合。如果他无法访问网络目录,他总是可以选择一个密码散列,并将其写入数据库。换句话说,哈希算法并不像系统安全那么重要,并且如果您不使用 SSL 并且限制登录尝试,那么攻击者可以只监听连接以获取信息。除非您需要算法花费很长时间来计算(出于您自己的目的),否则带有用户特定盐的 SHA-256 或 SHA-512就足够了。

作为一项附加的安全措施,设置一个脚本(bash、批处理、python 等)或程序,并给它一个晦涩的名称,并让它检查 login.php 是否已更改(检查日期/时间戳)并向您发送电子邮件如果有的话。还应该记录所有以管理员权限登录的尝试,并记录所有失败的登录数据库尝试,并将日志通过电子邮件发送给您。

于 2012-01-08T20:32:44.103 回答
3

每个人都在谈论这个,就像他们可以通过互联网被黑客入侵一样。如前所述,限制尝试使得无法通过 Internet 破解密码,并且与哈希无关。

盐是必须的,但复杂性或多种盐甚至都无关紧要。任何盐都可以阻止攻击者使用预制的彩虹表。每个用户唯一的盐可以阻止攻击者创建一个新的彩虹表来对付你的整个用户群。

当整个数据库遭到破坏时,安全性才真正发挥作用,然后黑客可以每秒对 md5 哈希执行 1 亿次密码尝试。SHA512 大约慢 10,000 倍。具有当今强大功能的复杂密码仍然需要 100 年才能使用 md5 进行暴力破解,而使用 SHA512 则需要 10,000 倍。盐根本不会阻止暴力破解,因为它们总是必须被知道的,如果攻击者下载了你的数据库,他可能无论如何都在你的系统中。

于 2011-06-14T13:51:21.977 回答
1

由于冲突问题,MD5 很糟糕——两个不同的密码可能生成相同的 md-5。

对此,Sha-1 非常安全。您存储密码的加盐 sha-1 版本的原因是,您的 swerver 不会将用户的密码保存在文件中,因为他们可能会与其他人的服务器一起使用。否则,有什么区别?

如果黑客以某种方式窃取了您的整个未加密数据库,则散列加盐密码的唯一作用就是防止他冒充用户以进行将来的登录 - 黑客已经拥有数据。

如果您的用户输入的是普通密码,那么攻击者拥有哈希值有什么好处?

即使拥有未来技术的黑客可以每秒生成一百万个 sha-1 密钥以进行暴力攻击,您的服务器是否会每秒处理一百万次登录以供黑客测试他的密钥?那是如果您让黑客尝试使用加盐 sha-1 而不是像普通登录那样的密码登录。

最好的办法是将错误的登录尝试限制在某个合理的数字——例如 25 次,然后让用户退出一两分钟。如果累积的错误登录尝试在 24 小时内达到 250 次,请关闭帐户访问权限并向所有者发送电子邮件。

于 2011-12-04T22:37:20.437 回答
1

使用argon2i。argon2密码散列函数赢得了密码散列竞赛。

如果无法使用argon2,其他合理的选择是scryptbcryptPBKDF2。维基百科有这些功能的页面:

MD5、SHA1 和 SHA256 是消息摘要,而不是密码散列函数。它们不适合此目的。

从 MD5 切换到 SHA1 或 SHA512 不会大大提高构建的安全性。计算 SHA256 或 SHA512 哈希非常快。使用普通硬件的攻击者仍然可以每秒尝试数千万次(使用单个 CPU)甚至数十亿次(使用单个 GPU)的哈希值。良好的密码散列函数包括减缓字典攻击的工作因素。

这里是给 PHP 程序员的一个建议:阅读PHP FAQ然后使用password_hash()

于 2013-12-18T12:48:41.023 回答
1

这是MD5和SHA1的比较。您可以清楚地了解哪个更好。

在此处输入图像描述

于 2016-05-15T06:09:01.587 回答
-1

让我们假设下一点:黑客窃取了我们的数据库,包括用户和密码(加密)。黑客使用他们知道的密码创建了一个虚假帐户。

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 绰绰有余。

于 2016-02-02T14:45:37.543 回答
-1

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
于 2019-08-15T06:56:22.417 回答