PHP函数使用password_hash,hash或MD5,具体取决于可用性

时间:2017-09-28 14:38:17

标签: php hash

我正在创建一个脚本,理想情况下喜欢使用password_hash函数将用户密码转换为哈希值,但是我想让哈希动态化以确保password_hash函数确实存在,所以我写了以下函数根据可用的函数返回哈希值。

function generateHash($hashpwd){
    if (function_exists('password_hash')) {
        return password_hash($hashpwd, PASSWORD_DEFAULT);
    } elseif (function_exists('hash')) {
        return hash('sha512', $hashpwd);
    } else {
        return md5($hashpwd);
    }
}

此方法有什么问题还是有效?我也用以下方式使用password_hash创建哈希:

password_hash($hashpwd, PASSWORD_DEFAULT);

但大多数地方我都看到了以下格式的示例语法:

password_hash($hashpwd, PASSWORD_DEFAULT)."\n";

区别是\ n是\ n是否需要\ n它是什么?

3 个答案:

答案 0 :(得分:5)

缺少password_hash(低于5.5)的每个PHP版本现在都是end-of-lifed并且结果不安全。它是a)不值得考虑这些现在危险不安全的PHP版本,以及b)不值得因为降级到MD5作为散列算法而对用户造成安全威胁。

  

但大多数地方我都看到了以下格式的示例语法:

password_hash($hashpwd, PASSWORD_DEFAULT)."\n";

我从来没有见过这样做过。 \n是一个新行。将其与哈希一起保存到数据库中会导致问题 - 如果您在某处输出哈希值进行调试/查看,那么它只值得做。

答案 1 :(得分:5)

  1. 单个未加盐的SHA512是password_hash的错误后备。至少你需要在这里使用不同的算法包括盐。最好使用crypt和一个不错的哈希算法,这就是password_hash所包含的。
  2. password_hash backport可用于PHP 5.3.7 + ,具体取决于您的操作系统甚至是某些旧版本。你现在不应该支持比这更早的东西。你需要在沙子的某处绘制线条。大多数新项目至少要求5.6+。如果您需要支持任何旧版本,请使用像PHPass这样的可信库,它向后兼容,直到PHP 3。
  3. password_hash($hashpwd, PASSWORD_DEFAULT)."\n";仅用于调试输出,尾随换行符是 密码哈希的一部分。

答案 2 :(得分:3)

您写道:

  

此方法有什么问题还是有效?我也用以下方式使用password_hash创建哈希:

password_hash($hashpwd, PASSWORD_DEFAULT);
  

但大多数地方我都看到了以下格式的示例语法:

password_hash($hashpwd, PASSWORD_DEFAULT)."\n";
  

区别是\ n是\ n是否需要\ n它是什么?

两者之间存在差异,

第二个将嵌入一个隐藏的换行符,这将使您的密码验证无声地失败。

根据this user contributed note关于使用Jay Blanchard提供的password_hash(),这是Stack Overflow上的成员。

  

使用将换行符\n连接到散列末尾的文档中的示例时要小心,即:

     

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";

     

人们使用连接的换行符存储哈希值,因此password_verify()将失败。

修改

2017年9月29日。

特别说明:

我今天在password_hash()重新访问了该手册,并注意到他们删除了用户提供的注释http://php.net/manual/en/function.password-hash.php#121017(由Jay Blanchard提供),其中修改了文档以删除\n引用,其中它现在读作:

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

从中删除了."\n"

现在这与提出的问题和答案有关。

我认为这与昨天提交的bug report有关,根据this comment在同一问题的另一个答案中提出。

我还必须注意,这种修改(手册的语法)可能会对以前发布的答案产生不利影响,说明网址不再有效。

就个人而言,我觉得他们应该在那里保留这个说明和/或说明以前的用法。