我一直在阅读密码哈希,但我看到的所有论坛都充满了人们辩论理论的帖子,我不太明白.

我有一个旧的(可能是非常弱的)密码脚本,如下所示:
$hash = sha1($pass1);

function createSalt()
{
$string = md5(uniqid(rand(),true));
return substr($string,3);
}

$salt = createSalt();
$hash = sha1($salt . $hash);

如果我理解正确,盐越长,黑客为了打破散列而产生的表越大.如果我错了,请纠正我

我正在寻找一个更安全的新脚本,我正在想这样的事情会好起来的:

function createSalt()
{
$string = hash('sha256',uniqid(rand(),true));
return $string;
}


$hash = hash('sha256',$password);
$salt = createSalt();
$secret_server_hash =     'ac1d81c5f99fdfc6758f21010be4c673878079fdc8f144394030687374f185ad';
$salt2 = hash('sha256',$salt);
$hash = $salt2 . $hash . $secret_server_hash;
$hash = hash('sha512',$hash );

这更安全吗?这是否有明显的开销?

最重要的是,有没有更好的方法来确保我的数据库中的密码不能(实际)通过密码分析恢复,从而确保安全性的唯一方式是通过我自己的编码错误?

编辑:

在阅读所有答案并进一步重新解析之后,我决定继续实施保护我密码的bcrypt方法.话虽如此,出于好奇的缘故,如果我把上面的代码放在上面的代码上,再循环一遍,就可以进行十万次迭代,这样做是否能够与bcrypt的实力/安全性相似?

盐只能帮助你到目前为止.如果您使用的散列算法非常快,以至于生成彩虹表几乎没有成本,您的安全性仍将受到损害.

几个指针:

>不要对所有密码使用单一盐.每个密码使用随机生成的盐.
>不要重新创建一个未修改的哈希(碰撞问题,see my previous answer,您需要无限量的哈希输入).
>不要尝试创建自己的哈希算法或混合匹配算法到复杂的操作.
>如果卡住了破碎/不安全/快速哈希原语,请使用key strengthening.这样可以增加攻击者计算彩虹表所需的时间.例:

function strong_hash($input,$salt = null,$algo = 'sha512',$rounds = 20000) {
  if($salt === null) {
    $salt = crypto_random_bytes(16);
  } else {
    $salt = pack('H*',substr($salt,32));
  }

  $hash = hash($algo,$salt . $input);

  for($i = 0; $i < $rounds; $i++) {
    // $input is appended to $hash in order to create
    // infinite input.
    $hash = hash($algo,$hash . $input);
  }

  // Return salt and hash. To verify,simply
  // passed stored hash as second parameter.
  return bin2hex($salt) . $hash;
}

function crypto_random_bytes($count) {
  static $randomState = null;

  $bytes = '';

  if(function_exists('openssl_random_pseudo_bytes') &&
      (strtoupper(substr(PHP_OS,3)) !== 'WIN')) { // OpenSSL slow on Win
    $bytes = openssl_random_pseudo_bytes($count);
  }

  if($bytes === '' && is_readable('/dev/urandom') &&
     ($hRand = @fopen('/dev/urandom','rb')) !== FALSE) {
    $bytes = fread($hRand,$count);
    fclose($hRand);
  }

  if(strlen($bytes) < $count) {
    $bytes = '';

    if($randomState === null) {
      $randomState = microtime();
      if(function_exists('getmypid')) {
        $randomState .= getmypid();
      }
    }

    for($i = 0; $i < $count; $i += 16) {
      $randomState = md5(microtime() . $randomState);

      if (PHP_VERSION >= '5') {
        $bytes .= md5($randomState,true);
      } else {
        $bytes .= pack('H*',md5($randomState));
      }
    }

    $bytes = substr($bytes,$count);
  }

  return $bytes;
}

而不是部署自己的(固有的缺陷)哈希/盐算法,为什么不使用由安全专业人士开发的?

使用bcrypt.这是为了这一点而开发的.缓慢和多轮确保攻击者必须部署大量资金和硬件才能破解您的密码.添加到每个密码盐(bcrypt REQUIRES盐),你可以确定攻击几乎是不可行的,没有可笑的资金或硬件.

Portable PHP Hashing Framework在非便携式模式下,您可以轻松地使用bcrypt生成散列.

您还可以使用crypt()函数生成输入字符串的bcrypt哈希值.如果你沿着这条路线走下去,确保每个哈希生成一个盐.

此类可以自动生成盐并根据输入验证现有散列.

class Bcrypt {
  private $rounds;
  public function __construct($rounds = 12) {
    if(CRYPT_BLOWFISH != 1) {
      throw new Exception("bcrypt not supported in this installation. See http://PHP.net/crypt");
    }

    $this->rounds = $rounds;
  }

  public function hash($input) {
    $hash = crypt($input,$this->getSalt());

    if(strlen($hash) > 13)
      return $hash;

    return false;
  }

  public function verify($input,$existingHash) {
    $hash = crypt($input,$existingHash);

    return $hash === $existingHash;
  }

  private function getSalt() {
    $salt = sprintf('$2a$%02d$',$this->rounds);

    $bytes = $this->getRandomBytes(16);

    $salt .= $this->encodeBytes($bytes);

    return $salt;
  }

  private $randomState;
  private function getRandomBytes($count) {
    $bytes = '';

    if(function_exists('openssl_random_pseudo_bytes') &&
        (strtoupper(substr(PHP_OS,3)) !== 'WIN')) { // OpenSSL slow on Win
      $bytes = openssl_random_pseudo_bytes($count);
    }

    if($bytes === '' && is_readable('/dev/urandom') &&
       ($hRand = @fopen('/dev/urandom','rb')) !== FALSE) {
      $bytes = fread($hRand,$count);
      fclose($hRand);
    }

    if(strlen($bytes) < $count) {
      $bytes = '';

      if($this->randomState === null) {
        $this->randomState = microtime();
        if(function_exists('getmypid')) {
          $this->randomState .= getmypid();
        }
      }

      for($i = 0; $i < $count; $i += 16) {
        $this->randomState = md5(microtime() . $this->randomState);

        if (PHP_VERSION >= '5') {
          $bytes .= md5($this->randomState,true);
        } else {
          $bytes .= pack('H*',md5($this->randomState));
        }
      }

      $bytes = substr($bytes,$count);
    }

    return $bytes;
  }

  private function encodeBytes($input) {
    return strtr(rtrim(base64_encode($input),'='),'+','.');
  }
}

您可以使用此代码:

$bcrypt = new Bcrypt(15);

$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password',$hash);

我们如何在PHP中创建一个相当安全的密码哈希?的更多相关文章

  1. 从iOS应用程序发送帖子到PHP脚本不工作…简单的解决方案就像

    我之前已经做了好几次了但是由于某些原因我无法通过这个帖子…我尝试了设置为_POST且没有的变量的PHP脚本……当它们未设置为发布时它工作精细.这是我的iOS代码:这里是PHP的一大块,POST变量不在正确的位置?我想这对于更有经验的开发人员来说是一个相当简单的答案,感谢您的帮助!解决方法$_POST是一个数组,而不是一个函数.您需要使用方括号来访问数组索引:

  2. swift算法实践2

    字符串hash算法Time33在效率和随机性两方面上俱佳。对于一个Hash函数,评价其优劣的标准应为随机性,即对任意一组标本,进入Hash表每一个单元之概率的平均程度,因为这个概率越平均,数据在表中的分布就越平均,表的空间利用率就越高。Times33的算法很简单,就是不断的乘33,见下面算法原型。

  3. swift学习2 元组 tuples

    swift中出现了一种新的数据结构,非常牛掰的元组tuples如果懂PHP的猿,会发现这个元组和PHP的数组非常类似,同样是可以默认不指定key,也可以指定key目前的学习疑问是,如何进行元组的遍历?

  4. 《Swift NSDictionary 的详细使用和部分方法介绍 和 哈希表散列)的阐述和解释 》

    /*《SwiftNSDictionary的详细使用和部分方法介绍和哈希表(散列)的阐述和解释》*//*第一步:我们首先,必须了解一个概念性的东西那就是:哈希哈希的主要解释是:哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。2》哈希列表是跟进式变化的。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。在哈希方法中使用的转换函数hash被称作哈希函数。按照此中算法构造出来的表叫做哈希表。

  5. Swift 中“等同性”、“比较”、“哈希” 概念理解

    甚至某些场景下还需要将其作为键值对中的Key,这就涉及到哈希函数以及哈希值的碰撞问题了。不过仔细查看代码,我们会发现上诉冲突的原因之一就是name、capital属性采用了同样的哈希函数。并修改Country中的哈希实现:改进后上诉冲突得以解决:总结本文简单的介绍了Swift中“等同性”、“比较”、“哈希”的概念,并对一些常见哈希冲突进行了分析。

  6. 尝试使用swift mailer,gmail smtp,php发送邮件

    这里是我的代码:在运行时出现此错误…

  7. Dictionary如何在Swift中使用Equatable协议?

    focusedCommentId=19980&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-19980What’sactuallyhappening:Wehashavalueonlyonceoninsertion.Wedon’tusehashesforcomparisonofelements,only==.Usinghashesforcomparisonisonlyreasonableifyous

  8. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  9. jQuery的Cookie封装,与PHP交互的简单实现

    下面小编就为大家带来一篇jQuery的Cookie封装,与PHP交互的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部