在这个例子中,我们将在Golang中创建一个一次性密码(OTP)库。它将利用基于时间的一次性密码(TOTP)和基于HMAC的一次性密码(HOTP)版本。这两个版本都尊重其IETF标准,即RFC 6238和RFC 4226。最后,尽管有些代码部分类似于现有的公共库*(如果你遵循标准,这是不可避免的*),这个例子没有使用任何公共库。
我们在这里使用了两个默认值。第一个是,OTP长度为6个字符,第二个是,周期为30秒。另外,你应该
-
缓存成功验证的代码,以防止被重复使用,例如90秒
-
在3次失败的尝试后阻止验证,例如30秒
-
将秘密与用户记录一起存储在一个持久性存储器中
-
将HOTP计数器与用户记录的秘密一起存储在一个持久性存储器中
-
如果用户决定禁用2FA,将用户的OTP记录从持久性存储中删除。
关于HOTP的建议 - 鉴于这是一个基于计数器的算法,允许用户扫描QR码来使用移动应用程序,使得计数器在客户端和服务器之间的漂移更加不可避免。例如,用户在应用程序中手动刷新代码,但从未提交,这在客户端增加了计数器,但在服务器端没有。如果您通过电子邮件或短信将代码发送给用户,使客户端和服务器端的计数器一致,那么HOTP就非常理想。CreateHOTPCode 功能就是专门用于这种目的的。
qr.go
package otp
package otp
secret.go
package otp
package otp
otp.go
// TOTP: https://en.wikipedia.org/wiki/One-time_password
package otp
测试
$ gotest -v ./...
使用方法
// Create secret