otp

package
v0.459.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2026 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package otp computes RFC 4226 HOTP and RFC 6238 TOTP one-time passwords. It is an offline post-exploitation primitive: when a 2FA seed has been recovered from captured loot (a secrets file, a config dump, an otpauth:// URI / QR payload), this derives the live codes — complementing the credential tooling (hash_identify, jwt_decode, kerberos_decode). It computes from an operator-supplied seed; it performs no network or device interaction.

Wrap-vs-native judgement

Native. HOTP is HMAC + the RFC 4226 dynamic-truncation; TOTP is HOTP over a time-step counter. Both are a dozen lines on top of the standard library's crypto/hmac + crypto/sha*. There is nothing to wrap.

Verifiable / no confidently-wrong output

This is the strongest verification class: RFC 4226 (Appendix D) and RFC 6238 (Appendix B) publish exact test vectors — seed "12345678901234567890", HOTP counter 0 -> 755224, TOTP SHA-1 T=59 -> 94287082, etc. The unit tests assert this package reproduces every published vector, so the algorithm ships only if it matches the authoritative reference.

Covered / deferred

Covered: HOTP, TOTP, the SHA-1 / SHA-256 / SHA-512 HMAC variants, 6-8 digit codes, base32 seed decoding (the Google-Authenticator form), and the otpauth:// key-URI parser (ParseURI — the 2FA-enrolment QR artifact, carrying the algorithm / digits / period that drive the code), and Steam Guard (SteamGuard — RFC 6238 over SHA1/30s mapped to Steam's 5-character alphabet, from a base64 shared_secret). Nothing in this package is deferred.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeSecret

func DecodeSecret(s string) ([]byte, error)

DecodeSecret decodes a base32 2FA secret, tolerating spaces, lowercase, and missing '=' padding (the common Google-Authenticator form).

func DecodeSecretBase64 added in v0.443.0

func DecodeSecretBase64(s string) ([]byte, error)

DecodeSecretBase64 decodes a base64 2FA secret — the form Steam stores its shared_secret in (the maFile / loot form), as opposed to the base32 Google- Authenticator form. Standard and raw (unpadded) base64 are both accepted.

func HOTP

func HOTP(key []byte, counter uint64, digits int, h func() hash.Hash) string

HOTP computes the RFC 4226 HOTP code for a key and counter.

func HashFor

func HashFor(algo string) (func() hash.Hash, error)

HashFor maps an algorithm name to its hash constructor.

func SteamGuard added in v0.443.0

func SteamGuard(key []byte, t time.Time) string

SteamGuard computes a Steam Guard mobile-authenticator code for time t. Steam uses RFC 6238 over an HMAC-SHA1 / 30-second step (T0 = 0) but, instead of the decimal modulo, maps the 31-bit truncated value to a fixed 5-character alphabet: take value mod 26 as an index five times, dividing by 26 each step. The seed is Steam's base64 shared_secret (decode with DecodeSecretBase64).

func TOTP

func TOTP(key []byte, t time.Time, period, digits int, h func() hash.Hash) string

TOTP computes the RFC 6238 TOTP code for time t (T0 = 0).

Types

type URIParams added in v0.442.0

type URIParams struct {
	Type       string // "totp" or "hotp"
	Secret     string // base32 secret (decode with DecodeSecret)
	Algorithm  string // SHA1 / SHA256 / SHA512 (default SHA1)
	Digits     int    // 6-8 (default 6)
	Period     int    // TOTP step seconds (default 30)
	Counter    uint64 // HOTP counter (valid only when HasCounter)
	HasCounter bool
	Issuer     string
	Account    string
}

URIParams holds the fields parsed from a Google-Authenticator otpauth:// key URI — the form encoded in a 2FA-enrolment QR code and emitted by authenticator exports. The secret is returned base32 (as it appears in the URI); decode it with DecodeSecret.

func ParseURI added in v0.442.0

func ParseURI(raw string) (*URIParams, error)

ParseURI parses an otpauth:// key URI per Google's Key-URI-Format

otpauth://TYPE/[ISSUER:]ACCOUNT?secret=BASE32&issuer=…&algorithm=…&digits=…&period=…&counter=…

into its fields, applying the spec defaults (algorithm SHA1, digits 6, period 30) for absent parameters. It exists so totp_generate can consume the real 2FA artifact directly: the URI carries the algorithm / digits / period that drive the code, so feeding the raw base32 secret alone (and relying on the SHA1/6/30 defaults) would silently produce wrong codes whenever the enrolment used, say, SHA256 or 8 digits. The label's ISSUER:ACCOUNT is parsed for display; an explicit issuer= query parameter wins over the label prefix.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL