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

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

时间: 2024-07-29 05:04:49

yii2的用户登录hash及其验证分析的相关文章

从零开始实现asp.net MVC4框架网站的用户登录以及权限验证模块 详细教程

用户登录与权限验证是网站不可缺少的一部分功能,asp.net MVC4框架内置了用于实现该功能的类库,只需要简单搭建即可完成该功能. 下面详细介绍该功能的完成方法,尾部有实例源码下载,希望可以给刚开始接触MVC的朋友做个参考.     第一步:给VS安装MVC4框架 VS2012自带MVC4框架,其他版本可以使用独立安装包进行安装,这里就不讨论了,本例使用VS2013创建,.NET4.0+MVC4 第二步:创建MVC4网站项目         选择文件-新建-项目,按下图示例创建一个空的MVC网

Openssh服务配置:控制用户登录 构建密钥对验证ssh

一.项目简介:OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现.OpenSSH提供了服务端后台程序和客户端工具,用来加密远程控制和文件传输过程中的数据,并由此来代替原来的类似服务.二.版本介绍:OpenSSH 支持 SSH 协议的版本 1.3.1.5.和 2.自从 OpenSSH 的版本2.9以来,默认的协议是版本2,该协议默认使用 RSA 钥匙.de:OpenSSH en:OpenSSHes:OpenSSH fr:OpenSSHit:OpenSSH ja:OpenS

yii2.0用户登录,退出判断(摘录)

文章来源:http://blog.sina.com.cn/s/blog_88a65c1b0101ix13.html 判断用户是否登录 在 Yii2.0 里面,判断用户是否已经登录,我们用下面的代码即可 Yii::$app->user->isGuest; 示例:如果用户已经登录,直接调用 goHome() 方法 if (!\Yii::$app->user->isGuest) { return $this->goHome(); } 获取登录用户名 在 yii2.0 里面,获取登录

thinkphp3.2用户登录ajax提交验证

html代码 <if condition="!isset($_SESSION['account'])"> <div class="load lf"> <p>注册登录</p> <div class="userId"> 帐号:<input type="text" placeholder="请输入帐号" value="" nam

单点登录CAS使用记(三):实现自定义验证用户登录

问题: CAS自带的用户验证逻辑太过简单,如何像正常网站一样,通过验证DB中的用户数据,来验证用户以及密码的合法性呢? 方案1:CAS默认的JDBC扩展方案: CAS自带了两种简单的通过JDBC方式验证用户的处理器. 1.QueryDatabaseAuthenticationHandler 2.SearchModeSearchDatabaseAuthenticationHandler 这两个处理类位于cas-server-support-jdbc这个扩展工程下. 第一步:改写用户验证处理器 打开

android loginDemo +WebService用户登录验证

本文是基于android4.0下的loginActivity Demo和android下的Webservice实现的.loginActivity是android4.0下的自带演示例程,他自带登录界面.用户名格式设定.输入密码和用户名格式是否正确.用户登录时间进度条等功能,用户可以在这个例程的基础上延伸出自己login用户登录程序.在这里我没有对这个程序做过多的延伸,只是增加Webservice验证用户登录的功能,使其成为一个完整的网络用户登录验证的模块程序.在这我会对这个Demo做全面的解析,使

Java入门:用户登录与注册模块1(实践项目)——分析

任务描述:用户登录与注册是大多数软件都拥有的一个模块.请编写一个控制台程序,实现用户的登录与注册功能,并且用户能够修改自己信息. [需求分析]由于本程序是一个演示程序,用户的信息我们做简化处理,仅包括:用户名.密码和EMAIL. 1.系统功能分析 分析一个系统或一个模块,我们首先需要了解系统需要实现哪些功能,通常可采用用例图来描述分析结果.对于本任务,用例图为: 对于每个用例,可以使用用例描述表来详细阐述用例内容.用户登录注册模块的三个用例描述表如下: (1)登录用例描述表 用例名称 登录 标识

Asp.Net使用加密cookie代替session验证用户登录状态 源码分享

首先 session 和 cache 拥有各自的优势而存在.  他们的优劣就不在这里讨论了. 本实例仅存储用户id于用户名,对于多级权限的架构,可以自行修改增加权限字段   本实例采用vs2010编写,vb和c#的代码都是经过测试的:一些童鞋说代码有问题的 注意下    什么? 你还在用vs2008 vs2005? 请自行重载 带有 optional 标致的函数   童鞋们提到的 密码修改后 要失效的问题 当时没有想到 个人认为 大致方向可以> >1. 每个用户生成1个xml 里面保存随机的几

【转】MVC4验证用户登录特性实现方法

在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeAttribute : FilterAttribute, IAuthorizationF