两步验证
两步验证(也称双因素身份验证,Two-factor authentication,简称2FA),还有多因素身份认证(MFA)。
因素越多,证明力就越强,身份就越可靠。
比较常见的实现方式是静态密码+一次性密码(One-time password,简称OTP)。
比如以前用过的这种硬Token。
(from Wikipedia)
当然还有软Token(如Google Authenticator,挺简洁的软件,最新版本已经支持备份了)。
(from Google Play)
上面的硬Token无法联网,软Token断网也能用。不需要和服务端通信?
一次性密码算法
有两种算法:基于散列消息验证码的一次性密码(HTOP)
、基于时间的一次性密码(TOTP)
。
服务端和客户端(Token)基于 相同的算法 、 相同的密钥 、 计数器 ,独立计算出一串密码。理论上两者的计算结果会是一样的。
其中计数器的值会变化,所以结果可以变化。
TOTP将计数器换成了时间戳,TOTP算是HTOP的一种实现。
时间戳可能由于网络延迟或时钟不同步等原因,两边的时间不一样,因此结果可能不一致。
为规避这个问题,服务端一般会有容错策略,会接受提前或滞后一段时间的密码。
密钥管理
一次性密码的密钥和静态密码同样重要。
开启两步验证的时候,服务端一般会提供一个二维码(或链接)、备份验证码。
建议将链接以及备份验证码加密(建议使用GnuPG
)备份,然后放到一个安全的地方。
不慎遗失的话,账号很可能找不回来了。
TOTP相关软件
简单介绍了两步验证的基础知识,下面就来介绍几款命令行版本的两步验证(TOTP版)工具。
Emacs-TOTP
emacs-totp
(Emacs 27.1+)
(from Github)
配置方法:大部分OTP的密钥是Base32 RFC4648
编码的,Emacs不支持,需要转换成Hex格式的。
部分密钥格式不是很标准,结尾缺少=(Padding),需要补全后再转换。
在线转换:base32-to-hex
,会自动补全结尾的Padding,挺方便。
命令行转换
1
| base32 -d <<<OV45GRTQARXOTU72TZLCBLUJDE2FYDSJ | xxd -g0 -p
|
Python版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| #!/bin/env python
# -*- coding:utf-8 -*-
import sys
import base64
if len(sys.argv) < 2:
print("Please input base32 format key")
sys.exit(-1)
key = sys.argv[1].strip()
length = len(key)
if length == 0:
print("Please input base32 format key")
sys.exit(-1)
# https://stackoverflow.com/questions/52012206/why-do-i-get-an-incorrect-padding-error-while-trying-to-decode-my-base32-strin
# https://datatracker.ietf.org/doc/html/rfc4648#section-6
mod = length % 8
if mod == 1:
key = key + "======"
if mod == 2:
key = key + "===="
if mod == 3:
key = key + "==="
if mod == 4:
key = key + "="
print("Base32 Format key: {}".format(key))
try:
print("Hex Format key: {}".format(base64.b32decode(key).encode('hex')))
except TypeError as e:
print("Decode failed, error: {}".format(str(e)))
|
OTP密钥加密保存
1
2
3
| ;;; 配置文件中加入以下语句,也可通过M-x customize-variable配置
(setq auth-source-gpg-encrypt-to '("your gpg key"))
(setq auth-sources '("~/.authinfo.gpg" "~/.authinfo" "~/.netrc"))
|
TOTP命令行
- pass-otp
,一款用来管理OTP Token的pass
软件扩展。其中,pass是一款简单的命令行版密码管理器,使用GPG加密密码文件。
- totp
(Go版本),用法见README。该作者还写了个C语言版本的ga-cmd
。