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身份验证器,就可以了:
利用命令行,也可以实现输出动态口令:
1 | ./otpauth -eval -link "otpauth-migration://offline?data=CjEKCo5%2BDJxcRfA2iwXXXXXXXXXXXXXXXXXXEoATACEAEYASAAKIPtjdj4%2F%2F%2F%2F%2FwE%3D" |
输出:
1 | 540059 堡垒机:zhangxxx |