Go library for generating and using One Time Passwords.
.gitignore | ||
common.go | ||
hotp_example_test.go | ||
hotp_test.go | ||
hotp.go | ||
LICENSE | ||
otp_test.go | ||
otp.go | ||
README.md | ||
totp_example_test.go | ||
totp_test.go | ||
totp.go |
otp
Go library for generating and using One Time Passwords. Supports both HOTP (RFC4226) and TOTP (RFC6238). Can be used for both server and client roles.
Examples
OTP Server
import (
"dev.justinjudd.org/justin/otp"
)
var Issuer = "example.com"
func CreateKeyForUser(user string) {
opts := otp.NewHOTPKeyOptions()
opts.Issuer = Issuer
opts.Label = user
key := otp.NewHOTPKey(opts)
// Store this string variable in your database
keyURL := key.URL()
// Provide the URL to the customer so they can include it in their 2FA client.
// Can email URL, or present QR code encoding of the URL
}
func CheckUsersCode(user string, code string) (bool, error) {
// Retrieve this string variable from your database
var keyURL string
key, err := otp.FromURL(keyURL)
if err != nil {
return false, err
}
// Ensure you are using the correct key
if key.Label != user {
return false, nil
}
success := key.Verify(code)
// Counter has been updated, update this info in the database
// Don't need this step for TOTP keys as the counter is time-based
keyURL = key.URL()
return success
}
OTP Client
import (
"dev.justinjudd.org/justin/otp"
)
// Just an example for storing OTP keys on the client
var keys map[Key]string
// Key is used as keys for the otp key storing map
type Key struct {
Issuer, Label string
}
func GetCode(issuer, username string) (string, error) {
mapKey := Key{issuer, username}
// Get the stored Key URL
keyURL, ok := keys[mapKey]
if !ok {
return "", nil
}
// Build the key from the URL
key, err := otp.FromURL(keyURL)
if err != nil {
return "", err
}
// Verify Issuer and Label are correct
if key.Issuer != issuer || key.Label != username {
return "", nil
}
code := key.OTP()
// If using HOTP, than need to save the state
keyURL = key.URL()
keys[mapKey]= keyURL
return code, nil
}