Understanding RFC 6238: How Time-Based One-Time Passwords (TOTP) Actually Work
Sarah Chen
Lead Cryptographer • 2FASafe Security Team
Introduction to RFC 6238 and RFC 4226
The Time-Based One-Time Password (TOTP) algorithm is an open standard published by the Internet Engineering Task Force (IETF) in RFC 6238. It is built as an extension of the HMAC-Based One-Time Password (HOTP) algorithm defined in RFC 4226. While HOTP relies on an incrementing event counter, TOTP replaces the counter with the current time step derived from the Unix Epoch.
The 4-Step Mathematical Pipeline of TOTP
Generating a 6-digit TOTP code involves four precise mathematical operations executed in sequence:
Step 1: Base32 Secret Key Decoding
The shared secret key provided during 2FA enrollment (e.g., JBSWY3DPEHPK3PXP) is encoded in RFC 4648 Base32 format. The authenticator strips spaces and converts the 32-character alphabet into a raw binary byte array (typically 10 to 20 bytes for HMAC-SHA1).
Step 2: Time Counter Calculation ($T$)
The Unix Epoch timestamp ($T_0$) represents the total seconds elapsed since January 1, 1970, 00:00:00 UTC. The counter $T$ is computed using integer division:
T = floor((Current_Unix_Time - T0) / Time_Step_X) // Default RFC 6238 parameters: T0 = 0, Time_Step_X = 30 seconds
The integer $T$ is then formatted as an 8-byte (64-bit) big-endian binary buffer.
Step 3: HMAC-SHA1 Cryptographic Hashing
The algorithm calculates a Hash-based Message Authentication Code (HMAC) over the 8-byte time counter using the shared secret key:
HMAC_Hash = HMAC-SHA1(Secret_Key_Bytes, 8_Byte_Time_Buffer) // Produces a 20-byte (160-bit) hash digest
Step 4: Dynamic Truncation and Modulo $10^d$
To convert the 20-byte hash into a user-friendly 6-digit number, RFC 4226 specifies Dynamic Truncation (DT):
- Take the lowest 4 bits of the last byte (Byte 19) to determine the offset index $O = \text{Byte}[19] \ \& \ 0x0F$.
- Extract 4 consecutive bytes starting from offset $O$: $\text{Bytes}[O \dots O+3]$.
- Mask the most significant bit to eliminate signed integer ambiguity ($\& \ 0x7FFFFFFF$).
- Calculate modulo $10^6$ ($1,000,000$) to yield a 6-digit integer padded with leading zeros.
Clock Drift Tolerance & Window Checking
Because physical device clocks may vary by a few seconds, standard RFC 6238 validation servers test both $T$ and adjacent intervals $T-1$ and $T+1$. This creates an acceptable tolerance window of ±30 seconds while blocking replay attempts from expired time windows.
Protect Your Accounts Today
Generate and test real-time 2FA codes with 100% client-side zero-knowledge security on 2FASafe.