PHP更安全的密码加密机制Bcrypt详解


Posted in PHP onJune 18, 2017

前言

我们常常为了避免在服务器受到攻击,数据库被拖库时,用户的明文密码不被泄露,一般会对密码进行单向不可逆加密——哈希。

常见的方式是:

哈希方式 加密密码
md5(‘123456') e10adc3949ba59abbe56e057f20f883e
md5(‘123456' . ($salt = ‘salt')) 207acd61a3c1bd506d7e9a4535359f8a
sha1(‘123456') 40位密文
hash(‘sha256', ‘123456') 64位密文
hash(‘sha512', ‘123456') 128位密文

密文越长,在相同机器上,进行撞库消耗的时间越长,相对越安全。

比较常见的哈希方式是 md5 + 盐,避免用户设置简单密码,被轻松破解。

password_hash

但是,现在要推荐的是 password_hash() 函数,可以轻松对密码实现加盐加密,而且几乎不能破解。

$password = '123456';
 
var_dump(password_hash($password, PASSWORD_DEFAULT));
var_dump(password_hash($password, PASSWORD_DEFAULT));

password_hash 生成的哈希长度是 PASSWORD_BCRYPT —— 60位,PASSWORD_DEFAULT —— 60位 ~ 255位。PASSWORD_DEFAULT 取值跟 php 版本有关系,会等于其他值,但不影响使用。

每一次 password_hash 运行结果都不一样,因此需要使用 password_verify 函数进行验证。

$password = '123456';
 
$hash = password_hash($password, PASSWORD_DEFAULT);
var_dump(password_verify($password, $hash));

password_hash 会把计算 hash 的所有参数都存储在 hash 结果中,可以使用 password_get_info 获取相关信息。

$password = '123456';
$hash = password_hash($password, PASSWORD_DEFAULT);
var_dump(password_get_info($hash));

输出

array(3) {
 ["algo"]=>
 int(1)
 ["algoName"]=>
 string(6) "bcrypt"
 ["options"]=>
 array(1) {
 ["cost"]=>
 int(10)
 }
}

注意:不包含 salt

可以看出我当前版本的 PHP 使用 PASSWORD_DEFAULT 实际是使用 PASSWORD_BCRYPT

password_hash($password, $algo, $options) 的第三个参数 $options 支持设置至少 22 位的 salt。但仍然强烈推荐使用 PHP 默认生成的 salt,不要主动设置 salt。

当要更新加密算法和加密选项时,可以通过 password_needs_rehash 判断是否需要重新加密,下面的代码是一段官方示例

$options = array('cost' => 11);
// Verify stored hash against plain-text password
if (password_verify($password, $hash))
{
 // Check if a newer hashing algorithm is available
 // or the cost has changed
 if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options))
 {
  // If so, create a new hash, and replace the old one
  $newHash = password_hash($password, PASSWORD_DEFAULT, $options);
 }
 // Log user in
}

password_needs_rehash 可以理解为比较 $algo + $optionpassword_get_info($hash) 返回值。

password_hash 运算慢

password_hash 是出了名的运行慢,也就意味着在相同时间内,密码重试次数少,泄露风险降低。

$password = '123456';
var_dump(microtime(true));
var_dump(password_hash($password, PASSWORD_DEFAULT));
var_dump(microtime(true));
 
echo "\n";
 
var_dump(microtime(true));
var_dump(md5($password));
for ($i = 0; $i < 999; $i++)
{
 md5($password);
}
var_dump(microtime(true));

输出

float(1495594920.7034)
string(60) "$2y$10$9ZLvgzqmiZPEkYiIUchT6eUJqebekOAjFQO8/jW/Q6DMrmWNn0PDm"
float(1495594920.7818)

float(1495594920.7818)
string(32) "e10adc3949ba59abbe56e057f20f883e"
float(1495594920.7823)

password_hash 运行一次耗时 784 毫秒, md5 运行 1000 次耗时 5 毫秒。这是一个非常粗略的比较,跟运行机器有关,但也可以看出 password_hash 运行确实非常慢。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP 开源框架22个简单简介
Aug 24 PHP
整理的9个实用的PHP库简介和下载
Nov 09 PHP
PHP动态分页函数,PHP开发分页必备啦
Nov 07 PHP
php empty() 检查一个变量是否为空
Nov 10 PHP
php和mysql中uft-8中文编码乱码的几种解决办法
Apr 19 PHP
如何使用微信公众平台开发模式实现多客服
Jan 06 PHP
简单谈谈php延迟静态绑定
Jan 26 PHP
PHP中让json_encode不自动转义斜杠“/”的方法
Feb 28 PHP
ThinkPHP框架分布式数据库连接方法详解
Mar 14 PHP
基于ThinkPHP5框架使用QueryList爬取并存入mysql数据库操作示例
May 25 PHP
php实现的支付宝网页支付功能示例【基于TP5框架】
Sep 16 PHP
PHP函数用法详解【初始化、嵌套、内置函数等】
Jun 02 PHP
Laravel中log无法写入问题的解决
Jun 17 #PHP
php下载远程大文件(获取远程文件大小)的实例
Jun 17 #PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
Jun 17 #PHP
PHP 7安装调试工具Xdebug扩展的方法教程
Jun 17 #PHP
thinkphp查询,3.X 5.0方法(亲试可行)
Jun 17 #PHP
php 生成加密公钥加密私钥实例详解
Jun 16 #PHP
详解yii2使用多个数据库的案例
Jun 16 #PHP
You might like
《五等分的花嫁》漫画完结!2020年10月第2期TV动画制作组换血!
2020/03/06 日漫
什么是MVC,好东西啊
2007/05/03 PHP
js中的escape及unescape函数的php实现代码
2007/09/04 Javascript
自己的js工具 Event封装
2009/08/21 Javascript
JSQL SQLProxy 的 php 版本代码
2010/05/05 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
javascript生成随机颜色示例代码
2014/05/05 Javascript
jQuery 写的简单打字游戏可以提示正确和错误的次数
2014/07/01 Javascript
JS小游戏之宇宙战机源码详解
2014/09/25 Javascript
JS取模、取商及取整运算方法示例
2016/10/13 Javascript
解析javascript图片懒加载与预加载的分析总结
2016/10/27 Javascript
jQuery插件jquery.kxbdmarquee.js实现无缝滚动效果
2017/02/15 Javascript
NodeJs的fs读写删除移动监听
2017/04/28 NodeJs
Vue.js简易安装和快速入门(第二课)
2017/10/17 Javascript
浅谈ng-zorro使用心得
2018/12/03 Javascript
JS apply用法总结和使用场景实例分析
2020/03/14 Javascript
详解JS预解析原理
2020/06/16 Javascript
python和bash统计CPU利用率的方法
2015/07/10 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
2018/02/02 Python
详解windows python3.7安装numpy问题的解决方法
2018/08/13 Python
利用Python将数值型特征进行离散化操作的方法
2018/11/06 Python
Python3自动签到 定时任务 判断节假日的实例
2018/11/13 Python
python3安装speech语音模块的方法
2018/12/24 Python
Django渲染Markdown文章目录的方法示例
2019/01/02 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
python爬取抖音视频的实例分析
2021/01/19 Python
微信小程序canvas实现水平、垂直居中效果
2020/02/05 HTML / CSS
猎人靴英国官网:Hunter Boots
2017/02/02 全球购物
纽约州一群才华横溢的金匠制作而成:Hearth Jewelry
2019/03/22 全球购物
美国家居装饰店:Z Gallerie
2020/12/28 全球购物
什么是View State?
2013/01/27 面试题
毕业生的自我评价分享
2013/12/18 职场文书
会计电算化个人求职信范文
2014/01/24 职场文书
《火烧云》教学反思
2014/04/12 职场文书
个人委托书
2014/07/31 职场文书
合伙购房协议样本
2014/10/06 职场文书