在我们的密码加密中常常使用md5或者sha1等,但是这些方法已经不是最优的解决方案,想到的方法是加盐,在php中加盐的方法有很多种,其中内置的方法password_hash比较经典,最近研究,感觉比md5、sha1等方法要好的多,特记之。
以下是本人封装的代码:
<?php
class hlinfo_Hash {
private $algo=PASSWORD_DEFAULT;
private function readCost(){
$timeTarget = 0.05; // 50 毫秒(milliseconds)
$cost = 8;
do {
$cost++;
$start = microtime(true);
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);
return $cost;
}
private function options(){
return ['cost' => $this->readCost(),];
}
public function pwd($pwd){
return password_hash($pwd, $this->algo, $this->options());
}
public function verify($pwd,$hash){
$msg=array("success"=>false,"newhash"=>false,"msg"=>"");
if (password_verify($pwd, $hash)) {
if (password_needs_rehash($hash, $this->algo, $this->options())) {
$newHash = $this->pwd($pwd);
$msg=array("success"=>true,"newhash"=>true,"msg"=>$newHash);
}else{
$msg=array("success"=>true,"newhash"=>false,"msg"=>"");
}
} else {
$msg=array("success"=>false,"newhash"=>false,"msg"=>"");
}
return $msg;
}
}
使用例子:
<?php
$cyh=new hlinfo_Hash();
#获取密码的hash值存库,
$hash=$cyh->pwd("123456");
echo "hash str:".$hash.";
#验证密码的正确性,$hash为存库的hash值,
$hrs=$cyh->verify("123456", $hash);
if($hrs['success']){
#程序判断是否重新生成hash值,
if($hrs['newhash']){
#重新生成hash值,更新数据库的hash值
$nhash=$hrs['msg'];
echo "认证成功,hash:".$nhash;
}else{
echo "认证成功,hash未更新!";
}
}else{
echo "verify false";
}