前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >身份验证器是如何验证我们的身份?

身份验证器是如何验证我们的身份?

作者头像
yumusb
发布2020-08-28 15:08:20
4K0
发布2020-08-28 15:08:20
举报
文章被收录于专栏:坏男孩坏男孩

​ 我以为我最初遇见他是在宝塔面板上,因为他可以方便的帮助我们进行身份验证。其实我们早就相遇在QQ安全中心手机版的口令里面(此处不确定是否是使用同一种算法,不过原理类似)。当初遇见他,我并不知道他是离线的。我以为谷歌身份验证器肯定是绑定谷歌账号的。后来找了半天,原来他只是个离线的软件。相信有很多同学和我一样的想法:离线身份验证器如何能使我们登录在线的场景?

​ 身份验证器是谷歌的产品。之前版本有开源仓库 https://github.com/google/google-authenticator。由于本人水平有限,本文使用第三方人员写的php实现方法来进行演示。https://github.com/PHPGangsta/GoogleAuthenticator

​ 首先我们可以看到仓库给出的演示代码:(以我练习两年半的水平加上了注释)

代码语言:javascript
复制
<?php
require_once 'PHPGangsta/GoogleAuthenticator.php';

$ga = new PHPGangsta_GoogleAuthenticator();
$secret = $ga->createSecret();
//生成秘钥并且输出
echo "Secret is: ".$secret."\n\n";

$qrCodeUrl = $ga->getQRCodeGoogleUrl('Blog', $secret);
echo "Google Charts URL for the QR-Code: ".$qrCodeUrl."\n\n";
//用这个秘钥生成一个二维码,方便手机录入,这里有一个自声明的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入手,看他是如何验证的。

代码语言:javascript
复制
    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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档