详解Google Authenticator工作原理

发表于2014-09-23 08:28| 10060次阅读| 来源CSDN| 16 条评论| 作者伍昆

Google二维码Google Authenticator算法
width="22" height="16" src="http://hits.sinajs.cn/A1/weiboshare.html?url=http%3A%2F%2Fwww.csdn.net%2Farticle%2F2014-09-23%2F2821808-Google-Authenticator&type=3&count=&appkey=&title=Google%20Authenticator%E6%98%AF%E8%B0%B7%E6%AD%8C%E6%8E%A8%E5%87%BA%E7%9A%84%E4%B8%80%E6%AC%BE%E5%8A%A8%E6%80%81%E5%8F%A3%E4%BB%A4%E5%B7%A5%E5%85%B7%EF%BC%8C%E6%97%A8%E5%9C%A8%E8%A7%A3%E5%86%B3%E5%A4%A7%E5%AE%B6Google%E8%B4%A6%E6%88%B7%E9%81%AD%E5%88%B0%E6%81%B6%E6%84%8F%E6%94%BB%E5%87%BB%E7%9A%84%E9%97%AE%E9%A2%98%E3%80%82%E9%82%A3%E4%B9%88%EF%BC%8CAuthenticator%E9%87%87%E7%94%A8%E4%BA%86%E5%93%AA%E4%BA%9B%E7%AE%97%E6%B3%95%EF%BC%9F%E5%8F%88%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%9A%84%EF%BC%9F%E4%B8%94%E7%9C%8B%E6%9C%AC%E6%96%87%E6%8A%80%E6%9C%AF%E8%A7%A3%E8%AF%BB%E3%80%82&pic=&ralateUid=&language=zh_cn&rnd=1457181396441" frameborder="0" scrolling="no" allowtransparency="true">摘要:Google Authenticator是谷歌推出的一款动态口令工具,旨在解决大家Google账户遭到恶意攻击的问题。那么,Authenticator采用了哪些算法?又是如何实现的?且看本文技术解读。

【编者按】Google Authenticator是谷歌推出的一款动态口令工具,旨在解决大家Google账户遭到恶意攻击的问题,在手机端生成动态口令后,在Google相关的服务登陆中除了用正常用户名和密码外,需要输入一次动态口令才能验证成功,此举是为了保护用户的信息安全。那么,Authenticator采用了哪些算法?又是如何实现的?且看本文技术解读。

很多手机用户会使用 Google Authenticator(谷歌身份认证)来生成认证令牌,与传统单因子密码不同,其采用的是更安全的双因子(2FA two-factor authentication)认证。FA是指结合密码以及实物(信用卡、SMS手机、令牌或指纹等生物标志)两种条件对用户进行认证的方法。只需要在手机上安装如此高大上的密码生成应用程序,就可以生成一个随着时间变化的一次性密码,用于帐户验证,而且这个应用程序不需要连接网络即可工作。

实际上Google Authenticator采用的算法是TOTP(Time-Based One-Time Password基于时间的一次性密码),其核心内容包括以下三点:

  • 一个共享密钥(一个比特序列);
  • 当前时间输入;
  • 一个签署函数。

共享密钥

共享密码用于在手机端上建立账户。密码内容可以是通过手机拍照二维码或者手工输入,并会被进行base32加密。

手工密码的输入格式如下:

[js] view plaincopyprint?
  1. xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

包含该令牌的二维码的内容是一个URL:

[js] view plaincopyprint?
  1. otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google
otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google

时间输入(当前时间)

输入的时间值来自于手机本身,一旦我们获得密钥后,就无需与服务器再进行通信了。但是最重要一点是务必确保手机上的时间是正确的,因为往后的步骤服务器会多次重复使用之前得到的时间值,服务器只会认准这个值。进一步说,服务器会比对所有提交的令牌以确认哪一个是你输入并提交的。

签署

签署所使用的方法是HMAC-SHA1。HMAC的全称是Hash-based message authentication code(哈希运算消息认证码),以一个密钥和一个消息为输入,生成一个消息摘要作为输出,这里以SHA1作为消息输入。使用HMAC的原因是:只有用户本身知道正确的输入密钥,因此会得到唯一的输出。其算法可以简单表示为:

[js] view plaincopyprint?
  1. hmac = SHA1(secret + SHA1(secret + input))
hmac = SHA1(secret + SHA1(secret + input))

事实上,TOTP是HMAC-OTP(基于HMAC的一次密码生成)的超集,区别是TOTP以当前时间作为输入,而HMAC-OTP以自增计算器作为输入,该计数器使用时需要进行同步。

算法

首先,要进行密钥的base32加密。虽然谷歌上的密钥格式是带空格的,不过base32拒绝空格输入,并只允许大写。所以要作如下处理:

[js] view plaincopyprint?
  1. original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
  2. secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))

第二步要获取当前时间值,这里使用的是UNIX time函数,或者可以用纪元秒。

[js] view plaincopyprint?
  1. input = CURRENT_UNIX_TIME()
input = CURRENT_UNIX_TIME()

在Google Authenticator中,input值拥有一个有效期。因为如果直接根据时间进行计算,结果将时刻发生改变,那么将很难进行复用。Google Authenticator默认使用30秒作为有效期(时间片),最后input的取值为从Unix epoch(1970年1月1日 00:00:00)来经历的30秒的个数。

[js] view plaincopyprint?
  1. input = CURRENT_UNIX_TIME() / 30
input = CURRENT_UNIX_TIME() / 30

最后一步是进行HMAC-SHA1运算

[js] view plaincopyprint?
  1. original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
  2. secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
  3. input = CURRENT_UNIX_TIME() / 30
  4. hmac = SHA1(secret + SHA1(secret + input))
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))

至此,2FA所需的两个因子都已准备就绪了。但是HMAC运算后的结果会是20字节即40位16进制数,应该没有人会愿意每次都输入这么长的密码。我们需要的是常规6位数字密码!

要实现这个愿望,首先要对20字节的SHA1进行瘦身。我们把SHA1的最后4个比特数(每个数的取值是0~15)用来做索引号,然后用另外的4个字节进行索引。因此,索引号的操作范围是15+4=19,加上是以零开始,所以能完整表示20字节的信息。4字节的获取方法是:

[js] view plaincopyprint?
  1. four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]

然后将它转化为标准的32bit无符号整数(4 bytes = 32 bit):

[js] view plaincopyprint?
  1. large_integer = INT(four_bytes)
large_integer = INT(four_bytes)

最后再进行7位数(1百万)取整,就可得到6位数字了:

[js] view plaincopyprint?
  1. large_integer = INT(four_bytes)
  2. small_integer = large_integer % 1,000,000
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000

这也是我们最后要的目标结果,整个过程总结如下:

[js] view plaincopyprint?
  1. original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
  2. secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
  3. input = CURRENT_UNIX_TIME() / 30
  4. hmac = SHA1(secret + SHA1(secret + input))
  5. four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
  6. large_integer = INT(four_bytes)
  7. small_integer = large_integer % 1,000,000

详解Google Authenticator工作原理相关推荐

  1. otg usb 定位_详解USB OTG工作原理及其应用

    原标题:详解USB OTG工作原理及其应用 1994年,Intel,Compaq等七家软硬件全球知名企业为了突破当时PC使用串口和并口传输速度的限制,成立了通用串行 开发者论坛( Implemente ...

  2. google authenticator python_谷歌验证器 Google Authenticator工作原理

    很多人都听过谷歌验证 (Google Authenticator) 或用过谷歌验证 (Google Authenticator) .尤其是随着比特币等虚拟货币的兴起,各大交易所都要求绑定谷歌验证 (G ...

  3. 图文并茂详解iptables 防火墙工作原理及知识点

    防火墙相关概念 iptables相关概念以及工作原理 iptables中四表五链的原理及规则 iptables中的基本命令详解 ------------------防火墙相关概念----------- ...

  4. 干货|8款开关电路设计详解,电路图+工作原理,图文结合,秒懂

    今天给大家分享的是:开关电源电路设计.工作原理图详解. 一.开关电源简介 开关电源又称交换式电源.开关变换器,是一种高频化电能转换装置,是电源供应器的一种.其功能是将一个位准的电压,透过不同形式的架构 ...

  5. google authenticator 工作原理

    Google authenticator 介绍 Google authenticator是一个基于TOTP原理实现的一个生成一次性密码的工具,用来做双因素登录,市面上已经有很多这些比较成熟的东西存在, ...

  6. 详解搜索引擎的工作原理

    一名合格的seo工程师,一定会了解搜索引擎的工作原理,对于百度和谷歌的原理几乎差不多,只是其中有些细节不同,比如分词技术等,因为国内搜索一般都是百度,所以我们以后的课程都会针对于百度,当然,基础类的只 ...

  7. MIDle生命周期详解,以及工作原理

    当MIDlet被应用程序管理器成功地初始化之后,就开始展开了它的生命周期.MIDlet的生命周期完全由应用程序管理器控制,也就是说,当MIDlet要从一个状态变成另外一个状态时,应用程序管理器会调用对 ...

  8. 详解Oracle架构、原理、进程,学会世间再无复杂架构

    详解Oracle架构.原理.进程,学会世间再无复杂架构 学习是一个循序渐进的过程,从面到点.从宏观到微观,逐步渗透,各个击破,对于Oracle, 怎么样从宏观上来理解呢?先来看一个图,这个图取自于教材 ...

  9. 详解SYN Flood攻击原理与防范

    详解SYN Flood攻击原理与防范 SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,它是利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被 ...

最新文章

  1. 一场开源数据库的精酿啤酒节,会有多少种味道?
  2. bzoj3522 Hotel
  3. php中系统函数的特征,php 常用的系统函数
  4. D. Binary Literature
  5. 美团点评技术年货:一本覆盖各技术领域、1200+页的电子书
  6. python高级属性 用法 编程_python高级编程之面向对象高级编程
  7. 无法从“cstring”转换为“lpcstr”_U盘重装系统后,无法使用?
  8. 关于嵌入式可执行程序,你了解多少?
  9. 解决 vs2010问题 error MSB8008: 指定的平台工具集(v110)未安装或无效
  10. Redis基础(三)——数据类型
  11. VS2010相同变量高亮显示设置
  12. PAT (Basic Level) Practice1021 个位数统计
  13. java batik_java – Batik传递库依赖项
  14. Ubuntu安装wechat的血泪史
  15. ios计算机错误,用iTunes更新IOS14失败,显示发生未知错误(4000)的简单解决办法!...
  16. “汇新杯”青年创客专项赛介绍
  17. php获得视频文件扩展名,php 获取文件扩展名的 n 种方法
  18. 时序分析 42 -- 时序数据转为空间数据 (一) 格拉姆角场
  19. Tableau仪表板制作
  20. 【物联网】思科扔下数颗物联网重磅炸弹,中国IoT圈却选择集体视而不见!

热门文章

  1. 用Three.js打造酷炫3D个人网站(含源码)
  2. 设置(setting)和其它设置
  3. python 根据cartopy插件出气象等值线高度场图片
  4. 短视频seo 矩阵系统源码私有化部署
  5. 企业微信生态下如何做好社群运营
  6. 中国历届奥运会金牌榜
  7. 查看内存占用,查看CPU占用,比较简单的命令,netstat -anp详细代表啥、ps -ef详细代表啥
  8. 复盘eygle在甲骨文大会上演讲中的示例,看看什么是大师的由点及面
  9. Nginx源码从模块开发入手,3个项目弄透nginx模块开发丨Linux服务器开发丨C++后端开发丨中间件开发丨分布式丨web服务器
  10. SCADA GPRS 通信协议制定