为什么php的password_hash这么慢?

Lyn*_*ynn 9 php password-hash password-encryption

password_hash用于密码加密.但是有一个奇怪的问题,password_hash花费很长时间.这是一个示例代码.此代码的成本将超过1秒.这是正常的吗?

<?php
  $startTime = microtime(TRUE);
  $password='123456';
  $cost=13;
  $hash=password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
  password_verify($password,$hash);
  $endTime = microtime(TRUE);
  $time = $endTime - $startTime;
  echo $time;
?>
Run Code Online (Sandbox Code Playgroud)

其结果是:1.0858609676361

tho*_*dic 13

在运行3v4l之后,这似乎完全正常.

密码哈希不是您想要优化的东西.用Leigh的hash文字说:

如果你是为了安全而哈希密码等,速度不是你的朋友.你应该使用最慢的方法.

缓慢的哈希意味着缓慢破解,并希望生成像彩虹表这样的东西比它的价值更麻烦.


cee*_*yoz 9

默认的算法password_hash,bcrypt设计成缓慢.

http://en.wikipedia.org/wiki/Key_stretching

在密码学中,密钥扩展指的是用于制作可能弱密钥的技术,通常是密码或密码短语,通过增加测试每个可能密钥所花费的时间来抵御暴力攻击更安全.人类创建的密码或密码通常很短或可预测,足以让密码破解.按键拉伸使这种攻击更加困难.

http://en.wikipedia.org/wiki/Rainbow_table#Defense_against_rainbow_tables

另一种有助于防止预计算攻击的技术是关键的扩展.使用拉伸时,salt,密码和许多中间散列值会多次通过底层散列函数运行,以增加散列每个密码所需的计算时间.例如,MD5-Crypt使用1000迭代循环,该循环重复地将salt,密码和当前中间散列值反馈回底层MD5散列函数.用户的密码哈希是salt值(非秘密)和最终哈希的串联.额外的时间对于用户来说并不明显,因为他们每次登录时都必须等待几分之一秒.另一方面,拉伸会降低蛮力攻击的有效性,与迭代次数成比例,因为它减少了攻击者在给定时间范围内可以执行的计算次数.该原则适用于MD5-Crypt和bcrypt.它还大大增加了构建预先计算的表所需的时间,但是在没有盐的情况下,这只需要进行一次.

一整秒可能有点长 - 您可以尝试减少$cost一到两次,以使其更多地达到十分之一秒,这将保留有效的保护,同时使用户无法察觉延迟.

  • @HuskyHuskie GPU每秒可以处理超过100亿个MD5哈希值.bcrypt哈希的十分之一秒是对彩虹表的充分保护. (2认同)

dec*_*eze 5

是的,这是正常的.这就是cost参数的用途:它允许您调整迭代计数,根据需要使哈希更慢或更快.

您应该始终尽可能慢地使哈希值尽可能快.原因是对密码哈希的唯一可行攻击是暴力破解.您希望使成本如此之大,以至于简单的暴力迫使所有可能的值变得过长.这是你唯一真正的防御密码哈希开始的攻击者.

一整秒似乎令人望而却步.你应该稍微降低这个成本,最多保持在几百毫秒之内.根据需要调整目标系统.