跳到主要内容

OTP算法原理

· 阅读需 2 分钟
Dawnbee
金融科技从业者

本文介绍了OTP的原理与实现。

技术规范

The service provider generates an 80-bit secret key for each user (whereas RFC 4226 §4 requires 128 bits and recommends 160 bits). This is provided as a 16, 26 or 32 character base32 string or as a QR code. The client creates an HMAC-SHA1 using this secret key. The message that is HMAC-ed can be:

the number of 30-second periods having elapsed since the Unix epoch (TOTP); or the counter that is incremented with each new code (HOTP). A portion of the HMAC is extracted and converted to a six-digit code.

伪代码实现

function GoogleAuthenticatorCode(string secret)
key := 5B5E7MMX344QRHYO
message := floor(current Unix time / 30)
hash := HMAC-SHA1(key, message)
offset := last nibble of hash
truncatedHash := hash[offset..offset+3] //4 bytes starting at the offset
Set the first bit of truncatedHash to zero //remove the most significant bit
code := truncatedHash mod 1000000
pad code with 0 from the left until length of code is 6
return code

OTP Algorithm Steps

Python实现

import pyotp

totp = pyotp.TOTP("JBSWY3DPEHPK3PXP")
print("Current OTP:", totp.now())

# OTP verified for current time
totp.verify('118427') # => False

uri = pyotp.totp.TOTP('JBSWY3DPEHPK3PXP').provisioning_uri("dawnbee@example.com", issuer_name="PyOTP")
print(uri)

生成二维码

<!doctype html>
<html>
<body>
<canvas id="qr"></canvas>
<script src="qrious.min.js"></script>
<script>
(function () {
var qr = new QRious({
element: document.getElementById("qr"),
value:
"otpauth://totp/PyOTP:dawnbee%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=PyOTP",
size: 400,
});
})();
</script>
</body>
</html>

参考资料

  1. https://en.wikipedia.org/wiki/Google_Authenticator
  2. https://www.jianshu.com/p/a7b900e8e50a
  3. https://github.com/neocotic/qrious