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

 更新时间:2014年10月15日 09:50:17   投稿:junjie  
这篇文章主要介绍了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

相关文章

  • Android中点击隐藏软键盘最佳方法

    Android中点击隐藏软键盘最佳方法

    本文介绍了Android中点击隐藏软键盘最佳方法。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • Android使用Spinner实现城市级联下拉框

    Android使用Spinner实现城市级联下拉框

    这篇文章主要为大家详细介绍了Android使用Spinner实现城市级联下拉框,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android EditText自定义样式的方法

    Android EditText自定义样式的方法

    这篇文章主要介绍了Android EditText自定义样式的方法,结合实例形式分析了EditText属性的含义及样式定义的技巧,需要的朋友可以参考下
    2016-02-02
  • Android自定义View实现地铁显示牌效果

    Android自定义View实现地铁显示牌效果

    这篇文章主要为大家详细介绍了Android自定义View实现地铁显示牌效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Android Flutter实现原理浅析

    Android Flutter实现原理浅析

    这篇文章主要介绍了Android Flutter的实现原理是怎么样的,flutter可以说是当下最流行的跨平台技术了,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Android开发壁纸的验证设置和确认功能实现demo

    Android开发壁纸的验证设置和确认功能实现demo

    android wallpaper包括锁屏壁纸和桌面壁纸,壁纸又区分静态和动态两种。本文详细介绍静态壁纸设置和确认,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-04-04
  • Android创建文件时出现java.io.IOException: Operation not permitted异常的解决方法

    Android创建文件时出现java.io.IOException: Operation not permitte

    最近使用android10创建文件失败,并抛出权限异常,这篇文章主要给大家介绍了Android创建文件时出现java.io.IOException: Operation not permitted异常的解决方法,需要的朋友可以参考下
    2023-05-05
  • Android应用内悬浮窗Activity的简单实现

    Android应用内悬浮窗Activity的简单实现

    悬浮窗相信大家应该都不陌生,下面这篇文章主要给大家介绍了关于Android应用内悬浮窗Activity简单实现的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • Android动态布局小结

    Android动态布局小结

    android动态布局相比静态布局,动态布局不用再将xml转变了布局代码,提高了一定的效率,本篇文章给大家介绍android动态布局小结,对android动态布局相关知识感兴趣的朋友一起学习吧
    2016-01-01
  • 浅谈Android View滑动冲突的解决方法

    浅谈Android View滑动冲突的解决方法

    本篇文章主要介绍了浅谈Android View滑动冲突的解决方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02

最新评论