HMAC-Based One-Time Password (HOTP/TOTP) Tester & Generator
Test and generate HOTP/TOTP codes using RFC 4226 & RFC 6238 standards. Supports SHA-1, SHA-256, SHA-512 with QR code export.
About
Misconfigured OTP parameters cause authentication lockouts. A wrong hash algorithm, an off-by-one counter, or a clock drift beyond the tolerance window means denied access and frustrated users. This tool computes HMAC-based One-Time Passwords per RFC 4226 (HOTP) and RFC 6238 (TOTP) entirely in your browser using the Web Crypto API. It accepts a Base32-encoded secret K, selects the hash function H โ {SHA-1, SHA-256, SHA-512}, and applies dynamic truncation to the resulting HMAC digest. For TOTP, the counter C is derived as (T โ T0)X where X defaults to 30 s. No server calls are made. Your secret key never leaves this page.
Pro tip: Most authenticator apps only support SHA-1 with 6 digits and 30-second periods. If you configure SHA-256 or SHA-512, verify your authenticator actually supports it. Many silently fall back to SHA-1, producing mismatched codes. This tool lets you validate exact parameter combinations before deploying to production. Note: TOTP accuracy depends on your device clock. A drift exceeding 30 s from UTC will produce codes that fail server-side validation unless the server implements a look-ahead/look-behind window.
Formulas
HOTP computation per RFC 4226:
HOTP(K, C) = Truncate(HMACโH(K, C)) mod 10d
Where Truncate applies dynamic truncation. Let HS = HMACโH(K, C). The offset o is the low-order 4 bits of the last byte of HS:
o = HS[len(HS) โ 1] โง 0x0F
Extract 4 bytes from HS at offset o, mask the most significant bit:
P = ((HS[o] โง 0x7F) << 24) | (HS[o+1] << 16) | (HS[o+2] << 8) | HS[o+3]
Final code: P mod 10d, zero-padded to d digits.
For TOTP (RFC 6238), the counter C is time-derived:
C = floor(T โ T0X)
Where K = shared secret key (Base32-decoded), C = counter value (8-byte big-endian), H = hash algorithm (SHA-1, SHA-256, or SHA-512), d = number of digits (6 - 8), T = current Unix time in seconds, T0 = epoch start (usually 0), X = time step in seconds (default 30).
Reference Data
| Parameter | RFC Default | Google Authenticator | Microsoft Authenticator | Authy | Notes |
|---|---|---|---|---|---|
| Algorithm | SHA-1 | SHA-1 only | SHA-1 / SHA-256 | SHA-1 only | RFC 6238 supports SHA-256/512 |
| Digits | 6 | 6 | 6 | 6 / 7 / 8 | Range: 6 - 8 |
| Period (X) | 30 s | 30 s | 30 s | 30 s | Some services use 60 s |
| Secret encoding | Base32 (RFC 4648) | Base32 | Base32 | Base32 | Padding optional |
| Min secret length | 128 bits | 80 bits | 128 bits | 128 bits | RFC recommends 160 bits for SHA-1 |
| Recommended secret (SHA-1) | 160 bits (20 bytes) | - | - | - | 32 Base32 chars |
| Recommended secret (SHA-256) | 256 bits (32 bytes) | - | - | - | 52 Base32 chars |
| Recommended secret (SHA-512) | 512 bits (64 bytes) | - | - | - | 103 Base32 chars |
| Counter size (HOTP) | 8 bytes | N/A | N/A | N/A | Big-endian unsigned 64-bit |
| Look-ahead window | 1 - 3 steps | 1 | 1 | 1 | Server-side tolerance |
| Resync threshold (HOTP) | 10 steps | - | - | - | RFC 4226 ยง7.4 |
| URI scheme | otpauth:// | Yes | Yes | Yes | De facto standard |
| T0 (epoch) | Unix epoch (0) | 0 | 0 | 0 | Seconds since 1970-01-01 |
| HMAC output (SHA-1) | 20 bytes | - | - | - | Truncated to 4 bytes |
| HMAC output (SHA-256) | 32 bytes | - | - | - | Truncated to 4 bytes |
| HMAC output (SHA-512) | 64 bytes | - | - | - | Truncated to 4 bytes |
| RFC 4226 test vector secret | 12345678901234567890 (ASCII) | - | - | - | Base32: GEZDGNBVGY3TQOJQ |
| RFC 6238 test vector (SHA-1) | Counter 1 โ 287082 | - | - | - | Time = 59 s |