How TOTP Works

Technical deep dive into the Time-Based One-Time Password algorithm and implementation

TOTP = HOTP(K, T)

K = Shared secret key between client and server

T = Time step counter (current Unix time / time step)

TOTP generates unique 6-8 digit codes that change every 30 seconds using cryptographic hash functions.

The TOTP Algorithm Step by Step

TOTP implementation follows RFC 6238 specification and builds upon HOTP (RFC 4226). Here's exactly how the algorithm generates those 6-digit codes:

1

Calculate Time Counter

Convert current Unix timestamp to a time-step counter by dividing by the time period (typically 30 seconds).

2

Decode Secret Key

Convert the base32-encoded shared secret into raw bytes. This secret is shared during initial setup.

3

Generate HMAC Hash

Use HMAC-SHA1 to hash the time counter with the secret key, producing a 20-byte hash value.

4

Dynamic Truncation

Extract a 4-byte dynamic binary code from the hash using the last 4 bits as an offset pointer.

5

Generate Final Code

Apply modulo operation to get the desired number of digits (typically 6) and pad with leading zeros.

Mathematical Formula

TOTP = DynamicTruncate(HMAC-SHA1(K, ⌊(T - T₀) / X⌋))

Where:
• K = Secret key
• T = Current Unix time
• T₀ = Unix time of initial counter time (default: 0)
• X = Time step in seconds (default: 30)

Code Implementation Example

Here's a simplified JavaScript implementation showing the core TOTP algorithm:

// Step 1: Calculate time counter function getTimeCounter(timeStep = 30) { return Math.floor(Date.now() / 1000 / timeStep); } // Step 2: Convert base32 to bytes function base32ToBytes(base32) { const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; // Implementation details... } // Step 3: HMAC-SHA1 hash generation async function hmacSha1(key, data) { const cryptoKey = await crypto.subtle.importKey( 'raw', key, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign'] ); return await crypto.subtle.sign('HMAC', cryptoKey, data); } // Step 4 & 5: Dynamic truncation function dynamicTruncate(hash, digits) { const offset = hash[hash.length - 1] & 0x0f; const code = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); return (code % Math.pow(10, digits)).toString().padStart(digits, '0'); }

Key Technical Components

Base32 Encoding

TOTP secret keys use base32 encoding (RFC 4648) instead of base64 because base32 is case-insensitive and avoids potentially confusing characters. The alphabet consists of A-Z and 2-7, making it more user-friendly for manual entry.

// Example base32 secret "JBSWY3DPEHPK3PXP" // Decoded to bytes: [72, 101, 108, 108, 111, 33, 222, 173, 190, 239]

HMAC-SHA1 Hash Function

TOTP uses HMAC-SHA1 for cryptographic hashing, which combines the SHA-1 hash function with a secret key. While SHA-1 has known vulnerabilities for general cryptographic use, it remains secure for TOTP because the hash output is truncated and time-limited.

Dynamic Truncation Process

The dynamic truncation algorithm extracts a 31-bit value from the 160-bit HMAC-SHA1 output:

  1. Take the last 4 bits of the hash as an offset (0-15)
  2. Extract 4 bytes starting from that offset
  3. Clear the most significant bit to ensure a positive number
  4. Apply modulo 10^digits to get the final code

Time Synchronization

TOTP relies on synchronized clocks between client and server. Most implementations allow for time drift tolerance:

Parameter Typical Value Purpose
Time Step 30 seconds How often codes change
Code Length 6 digits Balance between security and usability
Time Window ±1 step (±30s) Tolerance for clock drift
Hash Algorithm SHA-1 HMAC cryptographic function

Security Considerations

Cryptographic Strength: TOTP provides approximately 20 bits of entropy per 6-digit code (10^6 ≈ 2^20), making brute force attacks computationally infeasible within the 30-second validity window.

Attack Resistance

Important: TOTP security depends entirely on keeping the shared secret key confidential. If the secret is compromised, an attacker can generate valid codes indefinitely.

RFC 6238 Compliance

Our TOTP implementation strictly follows RFC 6238 standards, ensuring compatibility with all major authenticator applications and services. Key compliance points include:

See TOTP in Action

Experience the algorithm firsthand with our interactive TOTP generator

Try TOTP Generator