您的位置:首页 > 编程语言 > PHP开发

yii2的用户登录hash及其验证分析

2015-05-11 16:30 417 查看
使用gii生成用户表的model生成的几个方法解析:

随机数生成

protected function generateSalt($cost = 13)
{
$cost = (int) $cost;
if ($cost < 4 || $cost > 31) {
throw new InvalidParamException('Cost must be between 4 and 31.');
}

$rand = $this->generateRandomKey(20);
$salt = sprintf("$2y$%02d$", $cost);
$salt .= str_replace('+', '.', substr(base64_encode($rand), 0, 22));

return $salt;
}


(1)、生成随机数:$rand = $this->generateRandomKey(20);

(2)、加上前缀:$salt = sprintf("$2y$%02d$", $cost); $cost=13时默认前缀为$2y$13$

(3)、将$rand用base64加密,取前22位,并将+替换为.,最后加上前缀返回

原理,使用blowfish标准加密生成60个字符的hash,利用salt的最大长度(个人理解,salt最大长度应该是在21到22个字符之间),将hash作为salt与明文密码加密可得出一样的结果;密码最大为74个字符,超出则与74个字符密文相同;

setPassword()方法:

2、validatePassword($password)的方法

该方法会调用yii2/base/Security的validPassword()方法,

Security中的validPassword()方法会将用户输入的密码与数据库中的hash值一起加密

$test = crypt($password, $hash);

$n = strlen($test);

if ($n !== 60) {

return false;

}

return $this->compareString($test, $hash);

然后返回compareString($test, $hash)方法的结果

compareString方法:

//加上结束标记,防止mb_strlen()函数找不到结束标记

$expected .= "\0";
$actual .= "\0";

//调用mb_strlen($string, '8bit')函数按位获取字符串长度

$expectedLength = StringHelper::byteLength($expected);
$actualLength = StringHelper::byteLength($actual);

//获得长度差值
$diff = $expectedLength - $actualLength;
//循环对比每一位的ascii值是否相等(先将密文hash与用户输入加密后的字符串按位与,然后与diff按位或,返回结果)
 for ($i = 0; $i < $actualLength; $i++) {
$diff |= (ord($actual[$i]) ^ ord($expected[$i % $expectedLength]));
}
return $diff === 0;


用到的相关函数:

ord():

回字符串第一个字符的 ASCII 值

crypt(str,salt):

str:必需。规定要编码的字符串。
salt:可选。用于增加被编码字符数目的字符串,以使编码更加安全。如果未提供 salt 参数,则每次调用该函数时会随机生成一个。

mb_strlen():

获取字符串的长度,第二个参数为字符编码。如果省略,则使用内部字符编码。

PHP相关位运算符:

$a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1。

$a | $b Or(按位或) 将把 $a 和 $b 中任何一个为 1 的位设为 1。

$a ^ $b Xor(按位异或) 将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。

~ $a Not(按位取反) 将 $a 中为 0 的位设为 1,反之亦然。

$a << $b Shift left(左移) 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。

$a >> $b Shift right(右移) 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: