【问题标题】:Best way to store passwords in a mysql database? [duplicate]将密码存储在 mysql 数据库中的最佳方法? [复制]
【发布时间】:2012-09-13 05:20:33
【问题描述】:

可能重复:
How to best store user information and user login and password
How do you use bcrypt for hashing passwords in PHP?

我习惯使用我知道现在已经过时的 md5(),而且我听说 sha1() 也不安全。那么,考虑到安全性,如今在数据库中存储和检索密码的最佳方式是什么?如果你能提供一个小例子,我会很高兴。

谢谢!

【问题讨论】:

  • 你看过sha2()吗
  • @JvdBerg - 对于 1.9E9 组合,您需要大约 0.25 seconds 和 2012 年的 GPU。无需将它们存储在硬盘上,只需尝试(蛮力)直到找到匹配项。
  • @JvdBErg - 这是一个误解,salt 不能计入密码长度,它不是秘密,将与密码哈希一起存储。通过 SQL 注入攻击,您将获得这种盐。
  • @JvdBerg - 其实这是重点!它可以保护用户的密码,以防攻击者使用密码哈希访问数据库。此密码通常也用于其他网站。

标签: php mysql passwords


【解决方案1】:

你真的应该使用 bcrypt 来散列你的密码,它是专门为散列密码而设计的。

密码的哈希函数应该慢(需要一些计算时间)。大多数哈希算法(如 SHA-1 和 MD5 甚至 SHA-256)都被设计为速度很快,但这使得它很容易成为暴力攻击的目标。一个现成的 GPU 每秒能够计算大约 8 Giga MD5 哈希!

不要害怕使用 bcrypt!它不仅适用于高安全性站点,而且使用起来就像使用 md5 哈希一样简单。推荐使用像phpass这样完善的库,如果你想了解它是如何实现的,你可以阅读这个article,我试图解释最重要的点。

更新:

当前的 PHP 版本提供了函数 password_hash() 和 password_verify() 来处理密码。像这样使用它们:

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

【讨论】:

  • 以防万一有人想知道——bcrypt 在一般意义上并不慢(如果你愿意,你可以让它每秒散列成百上千个密码)。重要的是它不如 MD5 或 SHA1 快(每秒可以散列数亿个密码)。普通人不需要每秒散列数亿个密码,但攻击者却可以。
  • @Brendan Long - 确实,不同之处在于,它提供了一个成本因素,它决定了散列的迭代次数。将成本因子提高 1 倍,所需时间加倍,并使算法适用于未来(因此更快)的硬件。
【解决方案2】:

md5\sha1 + 独特的盐 = 最好的方法

不要偏执。

【讨论】:

  • md5\sha1 + uniqe salt 比你自己的自行车最好
  • 不,不是。它太快太复杂了。 Use bcrypt.
  • 他问的是 md5\sha1 而不是其他函数。我在 Rails 应用程序中使用 bcrypt,在 php 中使用 md5\sha1。
  • 语言的选择与它无关。 MD5 和 SHA1 不是为密码散列而设计的(更具体地说,它们不是key derivation functions)。为什么在存在安全函数时使用不安全函数?
【解决方案3】:

我建议查看 bcrypt,因为它可以帮助抵御暴力攻击。 http://codahale.com/how-to-safely-store-a-password/

你可以找到例子Here

【讨论】:

  • bcrypt 是唯一一种专为难以破解而设计的方法。 SHA1、SHA256 尤其是 MD5 是不够的。
  • bcrypt 不是 only 方法。还有 scrypt(使用更多内存——这是一件好事)和 PBKDF2(类似于 bcrypt,但不太好)。
【解决方案4】:

我们将crypt 与 Blowfish 一起使用:

// Hash our password
$hashed = crypt($plain_text_password, '$2a$08$' . substr(hash('whirlpool', microtime()), rand(0, 105), 22));

// Validate a password
if (crypt($plain_text_password, $hashed) == $hashed)) {
    // Valid password
}

盐前缀 $2a$(阅读文档)指示 crypt 使用 Blowfish。并且假设在底层操作系统中实现crypt(3) 支持它,您就可以“免费”获得它。

【讨论】:

  • 我真的不明白这部分在做什么:. substr(hash('whirlpool', microtime()), rand(0, 105), 22).
  • 它使用whirlpool算法根据当前时间生成一个128个字符的哈希值,然后从中提取22个字符并将它们附加到传递给crypt的盐中。
  • 您调用rand() 的次数越多,显然您的应用程序就越安全。 咧嘴
  • 如果你想要的只是盐,那么抓取 22 个字符的随机数据会更简单(也更快)..
【解决方案5】:

您可以查找很多加密代码或将它们混合在一起,例如:

sha1(md5(sha1($pw)));

我觉得没必要,所以我使用的是 SHA512 hash("sha512",$pw);

【讨论】:

  • 不。请不要发布这样的误导性答案。
  • 这不一定是个坏主意,但在这样做之前you should understand the implications。链接散列函数不会自动获得更好的安全性。
猜你喜欢
  • 2013-01-25
  • 1970-01-01
  • 2020-08-10
  • 2011-07-27
  • 2017-08-02
相关资源
最近更新 更多