关于 OTP 的介绍与实现见 OTP 介绍与实现。
使用 pyotp 可以方便地计算 OTP,不用自己实现了。
HOTP:
import pyotpimport base64secret = "12345678901234567890"b32secret = base64.b32encode(secret.encode()).decode()hotp = pyotp.HOTP(b32secret)# 计算 HOTPhotp.at(0) # => '755224'hotp.at(1) # => '287082'# 校验 HOTPhotp.verify('755224', 0) # => Truehotp.verify('755224', 1) # => False
TOTP:
import pyotpimport base64from datetime import datetimesecret = "12345678901234567890"b32secret = base64.b32encode(secret.encode()).decode()totp = pyotp.TOTP(b32secret)# 计算当前时间的 TOTP(方式一)totp.now()# 计算当前时间的 TOTP(方式二)now = datetime.now()totp.at(now)totp.interval - now.timestamp() % totp.interval # 可以这样计算出 TOTP 的剩余有效时间# 校验 TOTPtotp.verify('755224')totp.verify('755224', datetime.now())
:::info
使用 pyotp 时,secret 要先 base32 编码再传入 HOTP 或 TOTP 对象中,pyotp 会在其内部解码,使用解码后的值计算 OTP。
关于为什么要先 base32 编码,pyotp 中再解码,而不是直接传入 secret 的原因暂不知。
:::
