Bcrypt加密算法简介

xl_echo编辑整理,欢迎转载,转载请声明文章来源。更多IT、编程案例、资料请联系QQ:1280023003
百战不败,依不自称常胜,百败不颓,依能奋力前行。——这才是真正的堪称强大!!
本文转载自:http://www.php.cn/php-weizijiaocheng-376004.html


前言

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

常见的方式是:

哈希方式 加密密码
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,PASSWORDDEFAULT));vardump(passwordhash( p a s s w o r d , P A S S W O R D D E F A U L T ) ) ; v a r d u m p ( p a s s w o r d h a s h ( password, PASSWORD_DEFAULT));
password_hash 生成的哈希长度是 PASSWORD_BCRYPT —— 60位,PASSWORD_DEFAULT —— 60位 ~ 255位。PASSWORD_DEFAULT 取值跟 php 版本有关系,会等于其他值,但不影响使用。

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

$password = ‘123456’;

hash=passwordhash( h a s h = p a s s w o r d h a s h ( password, PASSWORD_DEFAULT);
var_dump(password_verify( password, p a s s w o r d , hash));
password_hash 会把计算 hash 的所有参数都存储在 hash 结果中,可以使用 password_get_info 获取相关信息。

password=123456; p a s s w o r d = ‘ 123456 ′ ; hash = password_hash( password,PASSWORDDEFAULT);vardump(passwordgetinfo( p a s s w o r d , P A S S W O R D D E F A U L T ) ; v a r d u m p ( p a s s w o r d g e t i n f o ( 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, p a s s w o r d , algo, options) o p t i o n s ) 的 第 三 个 参 数 options 支持设置至少 22 位的 salt。但仍然强烈推荐使用 PHP 默认生成的 salt,不要主动设置 salt。

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

options=array(cost=>11);//Verifystoredhashagainstplaintextpasswordif(passwordverify( o p t i o n s = a r r a y ( ‘ c o s t ′ => 11 ) ; / / V e r i f y s t o r e d h a s h a g a i n s t p l a i n − t e x t p a s s w o r d i f ( p a s s w o r d v e r i f y ( password, hash))//Checkifanewerhashingalgorithmisavailable//orthecosthaschangedif(passwordneedsrehash($hash,PASSWORDDEFAULT,$options))//Ifso,createanewhash,andreplacetheoldone$newHash=passwordhash($password,PASSWORDDEFAULT,$options);//Loguserinpasswordneedsrehash h a s h ) ) / / C h e c k i f a n e w e r h a s h i n g a l g o r i t h m i s a v a i l a b l e / / o r t h e c o s t h a s c h a n g e d i f ( p a s s w o r d n e e d s r e h a s h ( $ h a s h , P A S S W O R D D E F A U L T , $ o p t i o n s ) ) / / I f s o , c r e a t e a n e w h a s h , a n d r e p l a c e t h e o l d o n e $ n e w H a s h = p a s s w o r d h a s h ( $ p a s s w o r d , P A S S W O R D D E F A U L T , $ o p t i o n s ) ; / / L o g u s e r i n p a s s w o r d n e e d s r e h a s h 可 以 理 解 为 比 较 algo + optionpasswordgetinfo( o p t i o n 和 p a s s w o r d g e t i n f o ( hash) 返回值。

password_hash 运算慢

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

password=123456;vardump(microtime(true));vardump(passwordhash( p a s s w o r d = ‘ 123456 ′ ; v a r d u m p ( m i c r o t i m e ( t r u e ) ) ; v a r d u m p ( p a s s w o r d h a s h ( password, PASSWORD_DEFAULT));
var_dump(microtime(true));

echo “\n”;

var_dump(microtime(true));
var_dump(md5( password));for( p a s s w o r d ) ) ; f o r ( i = 0; i<999; i < 999 ; i++)
{
md5($password);
}
var_dump(microtime(true));
输出

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

float(1495594920.7818)
string(32) “e10adc3949ba59abbe56e057f20f883e”
float(1495594920.7823)
password_hash 运行一次耗时 784 毫秒, md5 运行 1000 次耗时 5 毫秒。这是一个非常粗略的比较,跟运行机器有关,但也可以看出 password_hash 运行确实非常慢

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值