在我們的密碼加密中常常使用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";
}