PHP 加密密码


php encrypting passwords

好的,我知道这个话题在stackoverflow中被提出了很多,但他们没有强调我正在寻找的答案。

使用我告诉的md5加密(那是不久前我在php的菜鸟(是安全的,但是如果你在好的老谷歌上查找它,它已经加密和解密。

所以我开始寻找其他地方,也就是这里。

我听说过所有的加密方法,例如SHA-1,MD5,SHA-2,SHA-256,SHA-512等。

很多人说使用我正在查看的Bcrypt,它与SHA-512相比。

人们说使用随机盐并将其保存在您的数据库中,这是愚蠢的,因为假设黑客入侵了您的数据库并获取了您所有密码的盐,因此这是一个小窗口,可以在黑客解密所有密码之前更改所有盐并继续到其他地方尝试它们,例如Facebook,谷歌和StackOverflow

所以我的问题是这样做最安全的方法(加密(使用 SHA-512(并使用也将存储在数据库中的随机盐(或使用固定盐,该盐硬连接到我的 php 代码中,它具有与数据库随机盐相同的安全性。

我已经阅读了很多关于此的帖子,

所以我想我知道我在说什么,我喜欢无动于衷,准确地说,我已经阅读了许多关于这个的帖子,大约 20 篇。

哦,差点忘了,如果多次加密密码或仅加密一次密码是否更安全?

感谢您对一篇过多的帖子的帮助

我很抱歉人们有点困惑,但我没有得到

其他人帖子的重点,我开始漫无边际地谈论加密,但我谈论的是哈希字符串。

对此感到抱歉

使用我告诉的md5加密(那是不久前我在php的菜鸟(是安全的,但是如果你在好的老谷歌上查找它,它已经加密和解密。

首先是吹毛求疵。它是散列而不是加密。哈希是一种方式。现在回答您的问题:不要使用md5()来散列密码。它不再安全了。它已经被打破了几年了。不仅发现了冲突(导致相同哈希的多个值(,而且 md5 可以用任何像样的 GPU 非常快速地进行暴力破解。

很多人说使用我正在查看的 Bcrypt,它与 SHA-512

你应该使用bcrypt。这是目前密码哈希的最佳选择。

人们说使用随机盐并将其保存在您的数据库中,这是愚蠢

不,这不是愚蠢的。加盐密码可防止攻击者为您的所有密码创建彩虹表。为了您的方便,ircmaxell 创建了一个密码库,可以在 GitHub 上找到。

一些相关文章和堆栈溢出帖子:

  • 有没有比 bcrypt 和 scrypt 更现代的密码散列方法?
  • bcrypt 常见问题
  • 彩虹表够了:您需要了解的安全密码方案
  • 你如何使用bcrypt在PHP中散列密码?
  • 介绍: 密码库
  • 正确腌制密码,反对胡椒的案例
  • OWASP 密码存储备忘单

更新

当PHP 5.5发布时,它将引入一种正确加密密码的简单方法。默认情况下,它将使用bcrypt,并自动为您的密码添加盐。当将来有更好的算法可用时(例如scrypt(,它将能够使用它。有关详细信息,请参阅有关此新功能的 RFC。它还将具有一项功能,可以检测当前散列密码的已使用算法,并在用户登录到更新(/更安全(的算法时自动更新它们。有关实现示例,请查看此 GitHub 要点。

如果您仍在使用旧版本的 PHP 并且无法更新,则可以使用 C API 的纯 PHP 实现,支持 PHP>= 5.3.7。此兼容 API 使用与 C API 完全相同的实现。

注意:使用更安全的 scrypt 会更好,但是到目前为止 PHP 不支持它。如果在某个时候确实如此,我将更新此答案。

您将哈希与加密混淆了。

我在用户名中的某些字符以及php代码中的字符串中加盐。从理论上讲,他们需要代码和数据库来弄清楚。

盐是值得的,因为它可以防止预先计算所有可能的结果。多轮也有助于减慢速度,但如果有人碰巧可以访问哈希并拥有多个 GPU 可供使用,则不会太多。具体回答这个问题,如果我是你,我可以使用bcrypt,那么我会的。如果您决定只使用 SHA-512 哈希,请使用盐和多轮(数万轮(。

此外,MD5 和 SHA1 哈希等是单向的。从哈希中获取原始输出的唯一方法是通过蛮力或纯粹的运气来猜测它。

> 2015 年 6 月更新:

如@PeeHa所述,PHP 5.5 包含一个内置机制和一个简短的教程/解释,用于使用 PHP 实现散列密码。您可以查看密码哈希。

可以使用以下方法进行密码哈希:

  • string password_hash ( string $password , integer $algo [, array $options ] )

password_hash(( 使用强单向创建新的密码哈希 哈希算法。password_hash(( 与 crypt(( 兼容。 因此,由 crypt(( 创建的密码哈希可以与 password_hash((。

  • boolean password_verify ( string $password , string $hash )

验证给定的哈希是否与给定的密码匹配。

您可能会收到来自用户的输入,因此为了防止SQL注入,我建议使用以下方法来清除输入:

您可以使用预准备语句,该语句允许您将用户输入安全地插入到 n 个 SQL 查询中:

 $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
 $stmt->bindParam(':name', $name);
 $stmt->bindParam(':value', $value);
 $name = 'one';
 $value = 1;
 $stmt->execute();

有关@Theos回答中准备好的陈述的更多信息。

其他替代方法是清除用户输入字符串:

  • string stripslashes ( string $str )

stripslashes(( 的一个示例用法是当 PHP 指令 magic_quotes_gpc 已打开(在 PHP 5.4 之前默认处于打开状态(,并且您 未将此数据插入到以下位置(例如数据库( 需要转义。例如,如果您只是输出数据 直接来自 HTML 表单。条带斜杠接口

  • string mysqli::escape_string ( string $escapestr )

此函数用于创建可在 一个 SQL 语句。给定的字符串被编码为转义的 SQL 字符串,考虑到当前字符集 连接。 real_escape_string接口