身份验证器是如何验证我们的身份?
时间:2022-07-24
本文章向大家介绍身份验证器是如何验证我们的身份?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
我以为我最初遇见他是在宝塔面板上,因为他可以方便的帮助我们进行身份验证。其实我们早就相遇在QQ安全中心手机版的口令里面(此处不确定是否是使用同一种算法,不过原理类似)。当初遇见他,我并不知道他是离线的。我以为谷歌身份验证器肯定是绑定谷歌账号的。后来找了半天,原来他只是个离线的软件。相信有很多同学和我一样的想法:离线身份验证器如何能使我们登录在线的场景?
身份验证器是谷歌的产品。之前版本有开源仓库 https://github.com/google/google-authenticator。由于本人水平有限,本文使用第三方人员写的php实现方法来进行演示。https://github.com/PHPGangsta/GoogleAuthenticator
首先我们可以看到仓库给出的演示代码:(以我练习两年半的水平加上了注释)
<?php
require_once 'PHPGangsta/GoogleAuthenticator.php';
$ga = new PHPGangsta_GoogleAuthenticator();
$secret = $ga->createSecret();
//生成秘钥并且输出
echo "Secret is: ".$secret."nn";
$qrCodeUrl = $ga->getQRCodeGoogleUrl('Blog', $secret);
echo "Google Charts URL for the QR-Code: ".$qrCodeUrl."nn";
//用这个秘钥生成一个二维码,方便手机录入,这里有一个自声明的schema
//otpauth://totp/infoATphpgangsta.de%3Fsecret%3DOQB6ZZGYHCPSX4AK 有info 有secret信息
$oneCode = $ga->getCode($secret);
//通过秘钥生成验证码(就是身份验证器实时显示的数字)
echo "Checking Code '$oneCode' and Secret '$secret':n";
//通过秘钥和验证码进行身份验证。
$checkResult = $ga->verifyCode($secret, $oneCode, 2); // 2 = 2*30sec clock tolerance
if ($checkResult) {
echo 'OK';
} else {
echo 'FAILED';
}
至此,我们已经有了身份验证器大致的工作流程:
服务器生成秘钥,分发给客户。客户有此秘钥就可以实时生成验证码,服务端根据此客户提供的验证码来和自己所存储的秘钥进行验证。验证通过既登陆成功。
既然如此,我们就直接从verifyCode入手,看他是如何验证的。
public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
{
if ($currentTimeSlice === null) {
$currentTimeSlice = floor(time() / 30);
}
// 如果时间没有指定的话,这个参数就是当前的时间/30.这就意味着我们的验证码的有效期是30S
if (strlen($code) != 6) {
return false;
}
//我们传入的验证码长度必须是6位数
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);//根据提供的秘钥和时间,获取验证码。此处的时间是真实时间/30后得到的。按照参数名字来看,应该叫做当前时间切片?
if ($this->timingSafeEquals($calculatedCode, $code)) {
return true;
}
}
// 上面的循环是一个容错机制。函数入口里面的时间/30,已经指明验证码是30S的有效期,但是服务端校验时候会把当前时间段左右个两个30秒(调用verifyCode的第三个参数)都去获取code,这样用户可以更`慢`的输入验证码,更方便验证。也可以防止网络波动性问题。不过我个人觉得,2这个有些太放纵用户了。干脆设置为1,更干脆直接不设置这个循环。失效就失效,让用户重新输入。
return false;
}
$checkResult = $ga->verifyCode($secret, $oneCode, 2);
当然,这一切都基于
this->getCode(
服务器端这两者的算法是相同的。并且是不可逆的。如果确实感兴趣。可以更加深一步的查看相关函数方法。如果不感兴趣的话,就只需要知道 :身份验证器是基于时间和秘钥,就可以了。
更多请参考 :https://github.com/PHPGangsta/GoogleAuthenticator
- 梯度是如何计算的
- Java 机器学习库Smile实战(二)AdaBoost
- 如何用excel urldecode解码把url编码转为汉字?
- Scikit-learn实战之 SVM回归分析、密度估计、异常点检测
- TensorFlow模拟简单线性模型小栗子
- web跨域解决方案
- Bootstrap幻灯轮播如何支持触屏左右滑动手势?
- JavaScript 调试小技巧
- 图片上传预览js
- Isolation Forest算法实现详解
- css继承样式怎么控制?用选择器
- wordpress站内搜索结果页URL伪静态如何操作
- 如何实现大图居中超过的部分两边自动隐藏
- Ubuntu16.04安装后开发环境配置和常用软件安装
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 单基因生信分析流程(6)单基因相似性分析
- 三阴性乳腺癌提取和分析
- 一日一技:更友好的格式化数据提取方案
- 『深度应用』YoloV5 RTX2080Ti TensorRT与PyTorch速度对比
- 0797-使用HDP或CDP的Atlas采集CDH6的元数据和血缘
- 现代通信理论与新技术 PPT笔记整理
- 找找规律——LeetCode题目6:Z字形变换
- 给你点信心——LeetCode题目7:整数反转
- Python -二叉树 创建与遍历算法(很详细,转自国外教程)
- APP流量来源追踪方式——Android篇
- 从浏览器输入网址回车到看到页面过程到底经历了什么?
- Flutter Bloc 官方文档(BlocBuilder翻译)
- OpenGL ES 3.0 | 统一变量和属性的概念与(在程序中的)获取流程、统一变量缓冲区对象详解、std140块规范、用 命名统一变量块 建立 统一变量缓冲区对象 的流程 和 相关API 和...
- 深入浅出SVM(PART III)
- 高频原题——LeetCode题目8:字符串转换整数 (atoi)