码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-11 18:04:05      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:yii2   php   

使用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”)。



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

标签:yii2   php   

原文地址:http://blog.csdn.net/likunlun1234/article/details/45645453

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!