Documentation
¶
Overview ¶
Package totp provides TOTP (RFC 6238) utilities for two-factor authentication.
Features:
- 6-digit codes, 30-second window, base32 secrets
- Recovery codes in 10-character RFC 4648 base32 format, stored as HMAC-SHA-256(pepper, code) — never as raw or salted hashes
- Secret encryption at rest using AES-GCM
Security:
- Adjacent window of +/-1 (~30s) absorbs clock drift
- Recovery code hashes require a server-side pepper; a leaked DB dump alone is insufficient to brute-force codes offline
- All comparisons of recovery hashes use hmac.Equal (constant-time)
- No secrets are ever logged
Index ¶
- Constants
- func DecryptSecret(ciphertext string, key []byte) (string, error)
- func EncryptSecret(plaintext string, key []byte) (string, error)
- func GenerateQRURI(secret, email, issuer string) string
- func GenerateRecoveryCodes(n int) []string
- func GenerateSecret() (string, error)
- func HashRecoveryCode(code string, pepper []byte) string
- func VerifyCode(secret, code string) bool
- func VerifyRecoveryCode(code, hash string, pepper []byte) bool
Constants ¶
const MinRecoveryPepperBytes = 32
MinRecoveryPepperBytes is the minimum length (in raw bytes, post base64 decode) accepted for the recovery-code pepper. 32 bytes is the natural HMAC-SHA-256 key size.
const RecoveryCodeLength = 10
RecoveryCodeLength is the number of characters in a recovery code. 10 chars of RFC 4648 base32 = 50 bits of entropy, drawn directly from crypto/rand.
Variables ¶
This section is empty.
Functions ¶
func DecryptSecret ¶
DecryptSecret decrypts a TOTP secret that was encrypted with EncryptSecret. The key must be exactly 32 bytes. Returns an error if the ciphertext is invalid, tampered with, or encrypted with a different key.
func EncryptSecret ¶
EncryptSecret encrypts a TOTP secret for at-rest storage using AES-256-GCM. The key must be exactly 32 bytes. Returns a base64-encoded string containing the nonce prepended to the ciphertext.
func GenerateQRURI ¶
GenerateQRURI builds an otpauth:// provisioning URI suitable for QR codes.
Format (RFC 6238 / Google Authenticator spec):
otpauth://totp/{issuer}:{email}?secret=...&issuer={issuer}&algorithm=SHA1&digits=6&period=30
func GenerateRecoveryCodes ¶
GenerateRecoveryCodes returns n cryptographically-random recovery codes. Each code is RecoveryCodeLength characters drawn from the RFC 4648 base32 alphabet, giving 50 bits of entropy per code.
func GenerateSecret ¶
GenerateSecret returns a fresh base32 TOTP secret (160-bit / 32-char).
func HashRecoveryCode ¶
HashRecoveryCode returns hex(HMAC-SHA-256(pepper, canonical(code))).
The pepper is a server-side secret loaded from configuration; an attacker who exfiltrates only the database cannot brute-force codes offline without it. Empty code or insufficiently-long pepper returns the empty string so callers can reject the hash before it is stored.
func VerifyCode ¶
VerifyCode verifies a 6-digit TOTP code against the secret. It checks the current time step plus +/-1 window (for clock drift).
func VerifyRecoveryCode ¶
VerifyRecoveryCode checks a recovery code against a stored HMAC-SHA-256 hash. Comparison uses hmac.Equal, which is constant-time over the length of the inputs.
Types ¶
This section is empty.