用Golang创建一个用于双因素认证(2FA)的一次性密码(OTP)库

343 阅读2分钟

在这个例子中,我们将在Golang中创建一个一次性密码(OTP)库。它将利用基于时间的一次性密码(TOTP)基于HMAC的一次性密码(HOTP)版本。这两个版本都尊重其IETF标准,即RFC 6238RFC 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