为什么密码散列,例如php';密码散列这么慢?

为什么密码散列,例如php';密码散列这么慢?,php,password-encryption,password-hash,Php,Password Encryption,Password Hash,我正在使用password\u hash进行密码加密。然而有一个奇怪的问题,密码\u散列花费了很长时间。下面是一个示例代码。 此代码将花费1秒以上的时间。这正常吗 <?php $startTime = microtime(TRUE); $password='123456'; $cost=13; $hash=password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]); password_verify($

我正在使用
password\u hash
进行密码加密。然而有一个奇怪的问题,
密码\u散列
花费了很长时间。下面是一个示例代码。 此代码将花费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;
?>

结果是:1.0858609676361

在上运行后,这似乎完全正常

密码哈希不是您想要优化的东西。用以下的话来说:

如果你为了安全而散列密码等,速度不是你的朋友。你应该用最慢的方法

散列的速度慢意味着破解的速度慢,这可能会让生成彩虹表之类的东西变得更麻烦


是的,这很正常。这就是
cost
参数的作用:它允许您调整迭代计数,根据需要使散列变慢或变快

您应该始终使哈希尽可能慢,并且尽可能快。原因是对密码哈希的唯一可行攻击是暴力。您希望使成本如此之大,以至于简单地强制执行所有可能的值需要花费令人望而却步的时间。这是你唯一真正的防御攻击者的密码哈希开始


一整秒钟似乎不适合你自己使用。您应该降低一点成本,最多停留在几百毫秒之内。根据需要调整您的目标系统

密码散列,
bcrypt
的默认算法是设计的速度较慢

在密码学中,密钥拉伸是指通过增加测试每个可能的密钥所需的时间,使可能的弱密钥(通常是密码或密码短语)更安全地抵御暴力攻击的技术。人类创建的密码或密码短语通常很短或可预测,足以允许密码破解。关键点拉伸使此类攻击更加困难

另一种有助于防止预计算攻击的技术是密钥拉伸。当使用拉伸时,salt、password和许多中间散列值将通过底层散列函数多次运行,以增加散列每个密码所需的计算时间。例如,MD5 Crypt使用1000次迭代循环,该循环反复将salt、密码和当前中间哈希值反馈回底层MD5哈希函数。用户密码散列是salt值(非机密)和最终散列的串联。用户不会注意到额外的时间,因为他们每次登录时只需等待几秒钟。另一方面,拉伸与迭代次数成比例地降低暴力攻击的有效性,因为它减少了攻击者在给定时间范围内可以执行的计算次数。这一原理应用于MD5加密和bcrypt。它还大大增加了构建预计算表所需的时间,但在没有salt的情况下,这只需要做一次


一整秒钟可能有点长-你可以尝试将
$cost
降低一到两秒,使其更接近十分之一秒,这将保留有效的保护,同时让用户无法察觉延迟。

首先,
密码散列
不是加密

password_hash()使用强单向散列算法创建新的密码散列。密码\u hash()与crypt()兼容。因此,crypt()创建的密码散列可以与password_hash()一起使用

散列是单向的,无论你传递给它什么,最终结果都是一样的,但是你无法从散列中得到原始字符串。这是密码的理想选择,因为您希望存储用户密码的模糊版本,以便在登录时轻松比较,而无需实际存储密码。这意味着,如果数据库被破坏,只要密码被散列,攻击者就不会得到密码,他们会得到基本上无用的散列密码(你可以使用rainbow表,我相信其他技术也可以得到散列,但这需要相当多的努力)

这就引出了你原来的问题。为什么密码散列速度慢?它们的速度很慢,因为从散列中获取原始字符串的唯一方法之一是重新生成该散列。因此,如果生成每个哈希需要1秒,那么它将成为一个比使用快速哈希(如
sha
版本的
md5
更大的时间接收器。快速散列对于除密码存储之外的几乎所有内容都非常有用


希望这能回答你的问题。顺便说一句,我强烈建议为每个用户生成一个唯一的salt,并将其作为选项之一传递到
password\u hash
。这个salt可以作为明文存储在数据库中,与哈希密码一起存储。对每个密码使用不同的salt会将其添加到密码中,因此潜在攻击者必须为数据库中的每个salt生成一个彩虹表。此时,攻击者可能会利用其他技术获取密码,而不是数据库漏洞。

是否需要打印密码?或者你想存储它?@Fatemeh我想这只是调试代码。@Burimi什么?因为什么是好的?@Fatemeh“使用盐渍md5作为密码是一个坏主意。不是因为md5的密码弱点,而是因为它很快。”13是bcrypt的最大成本,它翻译成消息“嘿,函数编写器,做你想做的任何事,但要让它尽可能强大”,因此,你实际上是在要求自己长时间地打电话——这需要尽可能多的合理的散列。这并不意味着它总是在一秒钟内进行哈希运算——这取决于硬件——但使用最大成本有点像“忽略时间,只需prod”