Documentation
¶
Overview ¶
Package otp provides tools for generating and validating one-time passwords (OTPs) according to the HOTP (RFC 4226) and TOTP (RFC 6238) standards.
Index ¶
- Constants
- func ConstantTimeEqual(x, y string) bool
- func DecodeSecret(s string) ([]byte, error)
- func EncodeSecret(secret []byte) string
- func FormatURI(u URI) (string, error)
- func GenerateHOTP(secret []byte, counter uint64, digits uint) (string, error)
- func GenerateSecret(n uint) ([]byte, error)
- func GenerateTOTP(secret []byte, timestamp time.Time, opts TOTPOptions) (string, error)
- func ValidateHOTP(secret []byte, code string, counter uint64, lookAhead uint, digits uint) (bool, uint64, error)
- func ValidateTOTP(secret []byte, code string, timestamp time.Time, skew uint, opts TOTPOptions) (matched bool, counter uint64, err error)
- type HashFunc
- type TOTPOptions
- type URI
Examples ¶
Constants ¶
const DefaultTimeStepSeconds int64 = 30
DefaultTimeStepSeconds defines the time step in seconds used to calculate the TOTP counter, as per RFC 6238.
Variables ¶
This section is empty.
Functions ¶
func ConstantTimeEqual ¶ added in v0.2.0
ConstantTimeEqual compares two OTP strings to prevent timing attacks.
func DecodeSecret ¶ added in v0.2.0
DecodeSecret decodes a base32-encoded secret string into raw bytes. Input is accepted in upper or lower case and without padding characters.
func EncodeSecret ¶ added in v0.2.0
EncodeSecret encodes secret as a base32 string without padding, suitable for provisioning URIs and QR codes.
func FormatURI ¶ added in v0.2.0
FormatURI encodes a URI as an otpauth:// string. Default values (SHA1, 6 digits, 30-second period) are omitted from the output. URI.Secret is base32-encoded without padding.
func GenerateHOTP ¶
GenerateHOTP generates a HMAC-based One-Time Password (HOTP) per RFC 4226 using the provided secret, counter, and the desired OTP length in digits.
Example ¶
secret := []byte("12345678901234567890")
counter := uint64(9)
digits := uint(6)
hotp, err := GenerateHOTP(secret, counter, digits)
if err != nil {
fmt.Println("Error generating HOTP:", err)
return
}
fmt.Printf("secret: 0x%x\n", secret)
fmt.Printf("counter: %d\n", counter)
fmt.Printf("digits: %d\n", digits)
fmt.Printf("HOTP: %s\n", hotp)
Output: secret: 0x3132333435363738393031323334353637383930 counter: 9 digits: 6 HOTP: 520489
func GenerateSecret ¶ added in v0.2.0
GenerateSecret returns a cryptographically random secret of n bytes, suitable for use with GenerateTOTP or GenerateHOTP.
RFC 4226 requires a minimum of 16 bytes (128 bits) and recommends at least 20 bytes (160 bits).
func GenerateTOTP ¶
GenerateTOTP generates a Time-based One-Time Password (TOTP) per RFC 6238 using the provided secret, timestamp, and the desired OTP length in digits. It allows for a custom hash function; if none is provided, SHA-1 is used by default.
Example ¶
secret := []byte("12345678901234567890")
layout := "2006-01-02 15:04:05"
parsedTime, err := time.Parse(layout, "2033-05-18 03:33:20")
if err != nil {
fmt.Println(err)
return
}
digits := uint(8)
fmt.Println("secret", secret)
fmt.Println("time", parsedTime)
fmt.Println("digits", digits)
totp, err := GenerateTOTP(secret, parsedTime, TOTPOptions{Digits: 8})
if err != nil {
fmt.Println("Error generating TOTP:", err)
return
}
fmt.Println("TOTP:", totp)
Output: secret [49 50 51 52 53 54 55 56 57 48 49 50 51 52 53 54 55 56 57 48] time 2033-05-18 03:33:20 +0000 UTC digits 8 TOTP: 69279037
func ValidateHOTP ¶ added in v0.2.0
func ValidateHOTP(secret []byte, code string, counter uint64, lookAhead uint, digits uint) (bool, uint64, error)
ValidateHOTP checks whether code matches the HOTP for secret at any counter step in [counter, counter+lookAhead]. It returns the next counter value the caller should store for replay prevention. A lookAhead of 0 requires an exact match; RFC 4226 recommends a default window of 10.
func ValidateTOTP ¶ added in v0.2.0
func ValidateTOTP(secret []byte, code string, timestamp time.Time, skew uint, opts TOTPOptions) (matched bool, counter uint64, err error)
ValidateTOTP checks whether code matches the TOTP for secret at timestamp, allowing skew steps in either direction for clock drift tolerance. It returns the matched counter step so callers can store it for replay prevention. A skew of 1 allows the previous and next 30-second windows (RFC 6238 recommendation).
Types ¶
type HashFunc ¶ added in v0.2.0
HashFunc is a function that returns a new hash.Hash, used to specify the hashing algorithm for OTP generation.
type TOTPOptions ¶ added in v0.2.0
type URI ¶ added in v0.2.0
type URI struct {
Type string // "totp" or "hotp"
Issuer string
Account string
Secret []byte // raw bytes (decoded from base32)
Algorithm string // "SHA1", "SHA256", or "SHA512"; empty defaults to SHA1
Digits uint // 0 defaults to 6
Period int64 // TOTP: seconds per window; 0 defaults to 30
Counter uint64 // HOTP: initial counter value
}
URI represents a parsed otpauth:// URI as defined by the Google Authenticator Key URI Format specification.
func ParseURI ¶ added in v0.2.0
ParseURI parses an otpauth:// URI and returns a URI. The secret query parameter is base32-decoded into URI.Secret. Period (TOTP) and Counter (HOTP) are always set, using spec defaults when the parameter is absent. Algorithm is normalized to uppercase.
func (URI) HashFunc ¶ added in v0.2.0
HashFunc returns the hash constructor for the URI's Algorithm field.
func (URI) TOTPOptions ¶ added in v0.2.0
func (u URI) TOTPOptions() (TOTPOptions, error)
TOTPOptions converts the URI into a TOTPOptions value ready for use with GenerateTOTP or ValidateTOTP. Zero-value fields use their spec defaults (SHA1, 6 digits, 30-second period) via TOTPOptions.withDefaults.