使用 Google Authenticator(谷歌身份验证器)

某些简单的业务场景需要一个管理后台,但是系统却没有复杂到需要引入一套用户体系。那么,谷歌身份验证器(Google Authenticator)可以作为管理后台的一种简单的身份认证方式。

Google Authenticator 是一款基于时间(TOTP)与哈希(HOTP)的一次性密码算法的两步验证软件令牌。其原理是通过密钥与时间或者计数器序列计算出一个六到八位的一次性密码。

其中 HOTP 算法需要服务端维护一个额外的计数器,需要客户端和服务端的计数器保持同步才能验证一致。而 TOTP 算法只要保证服务端和客户端的时间同步即可验证一致(默认时间误差窗口是30秒)。

服务端实现

本文采用 Python 的 PyOTP 库来实现服务端验证。

安装 PyOTP

shellpip install pyotp

创建密钥

pythonimport pyotp

# 生成一个 base32 编码的密钥
secret_key = pyotp.random_base32()

密码验证

基于时间的一次性密码

该算法要求服务器和客户端设备的时钟误差不超过30秒。

pythonfrom pyotp import TOTP

totp = TOTP(secret_key)
# 获取当前的一次性密码
password = totp.now()
# 验证一次性密码
if totp.verify(password):
    print('verification succeeded')
else:
    print('verification failed')

TOTP 提供一个 interval 的参数用于调整密码有效期,但是该参数对 Google Authenticator 无效。

基于计数器的一次性密码

该算法要求服务端和客户端的计数器保持一致。

pythonfrom pyotp import HOTP

# 计数器
counter = 123

htop = HTOP(secret_key)
# 获取当前的一次性密码
password = htop.at(counter)
# 验证一次性密码
if htop.verify(password, counter):
    print('verification succeeded')
else:
    print('verification failed')

生成URI

PyOTP 可以生成兼容 Google Authenticator 的 Key Uri 格式的链接。将链接转换成二维码就能用于 Google Authenticator 扫描。

pythonimport pyotp

pyotp.TOTP(secret_key).provisioning_uri('用户名', issuer_name='发行方')

pyotp.HOTP(secret_key).provisioning_uri('用户名', initial_count=0, issuer_name='发行方')

客户端实现

手机下载 Google Authenticator 应用。打开 APP,点击右上角+号,扫描之前生成的二维码添加配置。