Android中新引进的Google Authenticator验证系统工作原理浅析

为了改进Android的安全问题,Google在Android系统中引入了谷歌验证应用(Google Authenticator)来保证账号的安全。谷歌验证应用的使用方法是:用户安装手机客户端,生成临时身份验证码,提交到服务器验证身份,类似的验证系统还有Authy。Robbie在其GitHub页面发布了自己用Go语言实现的版本,并撰写了一篇博文来解释其工作原理。

通常来讲,身份验证系统都实现了基于时间的一次性密码算法,即著名的TOTP(Time-Based One-Time Password)。该算法由三部分组成:

1.一个共享密钥(一系列二进制数据)
2.一个基于当前时间的输入
3.一个签名函数

1、 共享密钥

用户在创建手机端身份验证系统时需要获取共享密钥。获取的方式包括用识别程序扫描给定二维码或者直接手动输入。密钥是三十二位加密,至于为什么不是六十四位,可以参考维基百科给出的解释。

对于那些手动输入的用户,谷歌身份验证系统给出的共享密钥有如下的格式:
复制代码 代码如下:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

256位数据,当然别的验证系统可能会更短。

而对于扫描的用户,QR识别以后是类似下面的URL链接:

otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google

2、 基于当前时间的输入

这个输入是基于用户手机时间产生的,一旦用户完成第一步的密钥共享,就和身份验证服务器没有关系了。但是这里比较重要的是用户手机时间要准确,因为从算法原理来讲,身份验证服务器会基于同样的时间来重复进行用户手机的运算。进一步来说,服务器会计算当前时间前后几分钟内的令牌,跟用户提交的令牌比较。所以如果时间上相差太多,身份验证过程就会失败。

3、 签名函数

谷歌的签名函数使用了HMAC-SHA1。HMAC即基于哈希的消息验证码,提供了一种算法,可以用比较安全的单向哈希函数(如SHA1)来产生签名。这就是验证算法的原理所在:只有共享密钥拥有者和服务器才能够根据同样的输入(基于时间的)得到同样的输出签名。伪代码如下:
复制代码 代码如下:
hmac = SHA1(secret + SHA1(secret + input))

本文开头提到的TOTP和HMAC原理类似,只是TOTP强调输入一定是当前时间相关。类似的还有HOTP,采用增量式计数器的方式,需要不断和服务器同步。

算法流程简介

首先需要用base32解码密钥,为了更方便用户输入,谷歌采用了空格和小写的方式表示密钥。但是base32不能有空格而且必须大写,处理伪代码如下:
复制代码 代码如下:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))

接下来要从当前时间获得输入,通常采用Unix时间,即当前周期开始到现在的秒数
复制代码 代码如下:
input = CURRENT_UNIX_TIME()

这里有一点需要说明,验证码有一个时效,大概是30秒。这种设计是出于方便用户输入的考虑,每秒钟变化的验证码很难让用户迅速准确输入。为了实现这种时效性,可以通过整除30的方式来实现,即:
复制代码 代码如下:
input = CURRENT_UNIX_TIME() / 30

最后一步是签名函数,HMAC-SHA1,全部伪代码如下:
复制代码 代码如下:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30
hmac = SHA1(secret + SHA1(secret + input))

完成这些代码,基本就已经实现了两次验证的功能。由于HMAC是个标准长度的SHA1数值,有四十个字符的长度,用户很难一次性正确输入,因此还需要做一些格式上的处理。可参考下面的伪代码:
复制代码 代码如下:
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000

时间: 2024-07-29 11:23:22

Android中新引进的Google Authenticator验证系统工作原理浅析的相关文章

Android艺术开发探索第四章——View的工作原理(上)

Android艺术开发探索第四章--View的工作原理(上) 这章就比较好玩了,主要介绍一下View的工作原理,还有自定义View的实现方法,在Android中,View是一个很重要的角色,简单来说,View是Android中视觉的呈现,在界面上Android提供了一套完整的GUI库,里面有很多控件,但是有时候往往并不能满足于需求,所以只有自定义View了,我们会简单的说下流程,然后再去实践 除了View的三大流程之外,View常见的回调方法也是必须掌握的,比如构造方法,onAttach,onV

javaScript中的this示例学习详解及工作原理

 这篇文章主要介绍了javaScript中的this示例学习详解及工作原理,大家参考使用吧 this的工作原理   如果一个函数被作为一个对象的方法调用,那么this将被指派为这个对象.   代码如下: var parent = {     method: function () {         console.log(this);     } };   parent.method(); // <- parent       注意这种行为非常"脆弱",如果你获取一个方法的引用

javaScript中的this示例学习详解及工作原理_基础知识

this的工作原理 如果一个函数被作为一个对象的方法调用,那么this将被指派为这个对象. 复制代码 代码如下: var parent = {    method: function () {        console.log(this);    }}; parent.method();// <- parent 注意这种行为非常"脆弱",如果你获取一个方法的引用并且调用,那么this的值不会是parent了,而是window全局对象.这让大多数开发者迷惑. 复制代码 代码如下

Node.js中require的工作原理浅析_node.js

几乎所有的Node.js开发人员可以告诉你`require()`函数做什么,但我们又有多少人真正知道它是如何工作的?我们每天都使用它来加载库和模块,但它的行为,对于我们来说反而是一个谜. 出于好奇,我钻研了node的核心代码来找出在引擎下发生了什么事.但这并不是一个单一的功能,我在node的模块系统的找到了module.js.该文件包含一个令人惊讶的强大的且相对陌生的核心模块,控制每个文件的加载,编译和缓存.`require()`,它的横空出世,只是冰山的一角. module.js 复制代码 代

书籍中的一个小样章-Java并发编程AQS原理浅析

AQS的全称为(AbstractQueuedSynchronizer),这个类也是在java.util.concurrent.locks下面.这个类似乎很不容易看懂,因为它仅仅是提供了一系列公共的方法,让子类来调用.那么要理解意思,就得从子类下手,反过来看才容易看懂.如下图所示: 图 5-15 AQS的子类实现 这么多类,我们看那一个?刚刚提到过锁(Lock),我们就从锁开始吧.这里就先以ReentrantLock排它锁为例开始展开讲解如何利用AQS的,然后再简单介绍读写锁的要点(读写锁本身的实

Android 中的注解详细介绍_Android

注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理. 归纳而言,Android中的注解大概有以下好处 提高我们的开发效率 更早的发现程序的问题或者错误 更好的增加代码的描述能力 更加利于我们的一些规范约束 提供解决问题的更优解 准备工作 默认情况下,Android中的注解包并没有包括在framework中,它独立成一个单独的包,通常我们需要引入这个包. dependencies

Android 中的注解深入探究_Android

本文系GDG Android Meetup分享内容总结文章 注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理. 归纳而言,Android中的注解大概有以下好处 提高我们的开发效率 更早的发现程序的问题或者错误 更好的增加代码的描述能力 更加利于我们的一些规范约束 提供解决问题的更优解 准备工作 默认情况下,Android中的注解包并没有包括在framework中,它独立成一个

深入分析安卓(Android)中的注解_Android

归纳而言,Android中的注解大概有以下好处       1.提高我们的开发效率       2.更早的发现程序的问题或者错误       3.更好的增加代码的描述能力       4.更加利于我们的一些规范约束       5.提供解决问题的更优解 准备工作 默认情况下,Android中的注解包并没有包括在framework中,它独立成一个单独的包,通常我们需要引入这个包. dependencies { compile 'com.android.support:support-annotat

Android 中的注解详细介绍

注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理. 归纳而言,Android中的注解大概有以下好处 提高我们的开发效率 更早的发现程序的问题或者错误 更好的增加代码的描述能力 更加利于我们的一些规范约束 提供解决问题的更优解 准备工作 默认情况下,Android中的注解包并没有包括在framework中,它独立成一个单独的包,通常我们需要引入这个包. dependencies