两步验证

两步验证(也称双因素身份验证,Two-factor authentication,简称2FA)1,还有多因素身份认证(MFA)。 因素越多,证明力就越强,身份就越可靠。2 比较常见的实现方式是静态密码+一次性密码(One-time password,简称OTP)3

比如以前用过的这种硬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