Google身份验证器与OTP

背景

我司登录堡垒机需要Google身份验证器 Authenticator APP验证,账号由于是别人的,导出分享给我的时候是个二维码但是。。。我的手机的Authenticator APP要扫条形码才能导入?????????不知道咋整了,只能接着深入了下原理。

二维码解析后格式大概是这样的:

1
otpauth-migration://offline?data=CjEKCo5%2BDXXXXXXXXXXXXXXXX6IAEoATACEAEYASAAKIPtjdj4%2F%2F%2F%2F%2FwE%3D

查了下资料,这个是采用了OTP算法,于是大概学习了下。

OTP原理

动态口令算法又叫一次性口令算法,英文写作OTP(One-Time Password Algorithm)。
OTP的算法一般不采用对称加解密算法(如DES,AES),而是采用单向散列算法(SHA-1等)。原因是这样的,拿时间型令牌说明,密钥+时间(动态因子)=OTP,时间是知道的,每分钟产生的动态口令能通过硬件知道,DES算法也是公开的,这样就有反推出密钥的可能性。而单向散列算法,即使知道通算法计算的结果OTP,由于算法保证单向,那么从根本上就断绝了反推密钥的途径。

OTP类型包括:

  • 时间同步(TOTP)
  • 事件同步(HOTP)
  • 挑战 / 应答(OCRA)

Google Authenticator 30s更新一次的,绝壁是使用了TOTP(Time-Based One-Time Password Algorithm) — 时间同步型动态口令。

HOTP

HOTP(HMAC-base On-Time Password)译为基于HMAC的一次性密码,也称事件同步的动态密码。

HOTP的工作原理

1
HTOP(K,C)=Truncate(HMAC−SHA−1(K,C))

客户端和服务器事先协商好一个密钥K,用于一次性密码的生成过程。此外,客户端和服务器各有一个计数器C,并且事先将计数值同步。而Truncate是为了获得一个符合HTOP要求的值。

TOTP

TOTP(Time-base One-Time Password)译为基于时间的一次性密码,也称时间同步的动态密码.

TOTP的工作原理:

1
TOTP=Truncate(HMAC−SHA−1(K,T))

TOTP是HOTP的一个变种,将HOTP中的计数器C替换为依托时间的参数T,T是由当前时间(CurrentUnixTime、初始时间(T0)、步长(X)决定的。即:

  • T=(CurrentUnixtime−T0)/X
  • T0: 开始计步初始化时间,默认为0
  • X : 步长steps,默认情况下为30s

TOTP的要求:

  • 客户端和服务器必须能够彼此知道或者推算出对方的Unix Time
  • 客户端和服务器端必须共享一个密钥
  • 算法必须使用HOTP作为其关键实现环节
  • 客户端和服务器端必须使用相同的步长X
  • 每一个客户端必须拥有不同的密钥
  • 密钥的生成必须足够随机
  • 密钥必须储存在防篡改的设备上,而且不能在不安全的情况下被访问或使用。
  • 对该算法中T的实现必须大于int32,因为它在2038年将超出上限。
  • T0和X的协商必须在之前的步骤中就已经做好了。

实现

github地址:https://github.com/dim13/otpauth

按照文档git clone下来,build后,运行二维码解析出来的链接:

1
$ ./otpauth -link "otpauth-migration://offline?data=CjEKCo5%2BDJxcRfA2iwXXXXXXXXXXXXXXXXXXEoATACEAEYASAAKIPtjdj4%2F%2F%2F%2F%2FwE%3D"

输出:

1
otpauth://totp/%E5%A0%A1%E5%9E%92%E6%9C%BA:zhangxxx?algorithm=SHA1&digits=6&issuer=%E5%A0%A1%E5%9E%92%E6%9C%BA&period=30&secret=HEHEHEHEHEHE

可以得到如下参数:

  • algorithm=SHA1 (散列算法)
  • digits=6 (输出数字长度)
  • issuer=%E5%A0%A1%E5%9E%92%E6%9C%BA (urlencode后是中文堡垒机
  • period=30 (步长)
  • secret=HEHEHEHEHEHE (散列密钥)

将这些信息填到Google身份验证器,就可以了:

upload successful

利用命令行,也可以实现输出动态口令:

1
$ ./otpauth -eval -link "otpauth-migration://offline?data=CjEKCo5%2BDJxcRfA2iwXXXXXXXXXXXXXXXXXXEoATACEAEYASAAKIPtjdj4%2F%2F%2F%2F%2FwE%3D"

输出:

1
540059 堡垒机:zhangxxx