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)
  keyURL := key.URL()
  Store(user, keyURL)
  // 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
}
// Store this string variable in your database
func Store(user, url string) {
}
// Retrieve the url string variable from your database
func GetURL(user string) string {
  return ""
}
func CheckUsersCode(user string, code string) (bool, error) {
  keyURL := GetURL(user)
  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, nil
    }
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
}
Description
				
					Languages
				
				
								
								
									Go
								
								100%
							
						
					