Tiger_Auth_Totp

@api

Tiger_Auth_Totp — RFC 6238 time-based one-time passwords (the "authenticator app" factor), dependency-free.

Hand-rolled rather than pulled from Composer for the same reason the SES SigV4 signer is: TOTP is small, frozen (the RFC hasn't moved since 2011), and universally interoperable (Google Authenticator, Authy, 1Password, Microsoft Authenticator all speak the same SHA-1 / 6-digit / 30-second defaults). Owning ~80 lines beats owning a dependency.

The shared secret is base32 (RFC 4648) — that's what authenticator apps expect in the otpauth:// URI and in manual entry. Storage/encryption of the secret is NOT this class's job (see Tiger_Crypto + Tiger_Model_UserCredential); this is pure math.

Methods

generateSecret()

generateSecret($bytes = 20)

A fresh random shared secret, base32-encoded. 20 bytes = 160 bits = the RFC 4226 recommended HMAC-SHA1 key length; encodes to 32 base32 chars.

  • $bytes int — random key length in bytes

Returns string — the base32-encoded secret

uri()

uri($secret, $account, $issuer)

The otpauth://totp/... provisioning URI an authenticator app consumes (via QR or manual paste). issuer and account are shown to the user in their app.

  • $secret string — the base32 shared secret
  • $account string — the account label (usually the user's email)
  • $issuer string — the issuer label (the app/site name)

Returns string — the otpauth:// URI

verify()

verify($secret, $code, $window = 1, $at = null)

Verify a user-entered code against the secret, tolerating +/- $window steps of clock drift (1 = accept the previous, current, and next 30s code — the common default). Constant-time compared.

  • $secret string — base32 shared secret
  • $code string — the 6 digits the user typed
  • $window int — drift tolerance in periods
  • $at int|null — unix time to evaluate at (null = now; for tests)

Returns bool

codeAt()

codeAt($secret, $counter)

The HOTP value for a given counter (RFC 4226 §5.3 dynamic truncation), as a zero-padded DIGITS-length string.

  • $secret string — the base32 shared secret
  • $counter int — the moving-factor counter

Returns string — the zero-padded code

base32Encode()

base32Encode($raw)

Encode raw bytes to base32 (no padding).

  • $raw string — the raw bytes

Returns string — the base32 encoding

base32Decode()

base32Decode($b32)

Decode a base32 string to raw bytes (ignores spaces/padding/case).

  • $b32 string — the base32 string

Returns string — the decoded raw bytes