The Secret Mathematics Behind Your 6-Digit 2FA Code: Building an Authenticator from Scratch + Video

Listen to this Post

Featured Image

Introduction

Modern authentication has undergone a radical shift from trust-based systems to mathematically verifiable proofs. When a user generates a six-digit code on Google Authenticator, no data travels between the device and the server—yet both parties arrive at the identical number. This cryptographic sleight of hand relies on Time-based One-Time Password (TOTP) algorithms, deterministic functions, and bit-level truncation. Understanding how these building blocks work reveals why contemporary security architectures are moving toward public-key cryptography and passwordless authentication.

Learning Objectives

  • Understand the mathematical foundations of TOTP and HMAC-SHA1
  • Learn to implement a basic authenticator algorithm manually
  • Explore the evolution from static passwords to public-key authentication (WebAuthn)
  • Identify security trade-offs in time-based OTP systems
  • Apply practical commands for generating and verifying TOTP codes

You Should Know

  1. The Mathematics of TOTP: How Two Parties Agree Without Talking

TOTP (RFC 6238) is built on top of HMAC-based One-Time Password (HOTP, RFC 4226). The core formula is:

TOTP = HOTP(K, T) = Truncate(HMAC-SHA1(K, T)) mod 10^6

Where:

  • K = shared secret (base32 encoded)
  • T = counter derived from current Unix time divided by time step (usually 30 seconds)
  • Truncate = dynamic truncation extracting 31 bits from HMAC result
  • mod 10^6 = last 6 digits

The magic lies in the fact that both parties compute the same HMAC-SHA1 using the identical secret and synchronized time counter. The server stores the secret during enrollment; the user’s device stores it locally. No further communication occurs until verification.

Step‑by‑step manual simulation (Python pseudocode):

import hmac
import hashlib
import time
import struct
import base64

def hotp(secret, counter, digits=6):
 Convert counter to 8-byte big-endian
msg = struct.pack(">Q", counter)
 Compute HMAC-SHA1
h = hmac.new(base64.b32decode(secret, casefold=True), msg, hashlib.sha1).digest()
 Dynamic truncation: get last 4 bits of last byte as offset
offset = h[-1] & 0x0F
 Extract 4 bytes starting at offset, mask most significant bit
code_bytes = h[offset:offset+4]
code_int = struct.unpack(">I", code_bytes)[bash] & 0x7FFFFFFF
 Return modulo 10^digits
return code_int % (10  digits)

def totp(secret, step=30):
return hotp(secret, int(time.time()) // step)

Linux command‑line verification:

 Generate TOTP using oathtool (install via: sudo apt install oathtool)
SECRET="JBSWY3DPEHPK3PXP"  Example base32 secret
oathtool --totp -b $SECRET

Verify a given code at current time
oathtool --totp -b $SECRET -d 6 -w 0 <CODE>

Windows PowerShell equivalent:

 Requires .NET and manual base32 decoding; simpler: use WSL or compiled tool
 Example using custom PS module or online verification
  1. HMAC-SHA1 Deep Dive: Why SHA‑1 Still Lives in TOTP

Despite SHA‑1 being deprecated for digital signatures, it remains the default for TOTP due to legacy standardization (RFC 4226/6238) and the limited attack surface. The algorithm’s collision resistance is irrelevant here because the attacker never sees raw hashes—only truncated 6‑digit codes. The critical property is its pseudorandom function behavior.

HMAC construction:

HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))

Where:

– `K’` = K padded to block size
– `ipad` = 0x36 repeated
– `opad` = 0x5C repeated

Practical test with OpenSSL:

 Compute HMAC-SHA1 of message "hello" with key "world"
echo -n "hello" | openssl dgst -sha1 -hmac "world"

3. Time Synchronization and Drift Handling

TOTP assumes clocks are loosely synchronized. Real-world implementations allow a window of ±1 time step to accommodate network latency or slight drift. This is why you can often reuse a code within 60 seconds even though it refreshes every 30.

Code snippet with drift tolerance (Python):

def verify_totp(secret, user_code, window=1):
current = int(time.time()) // 30
for i in range(-window, window+1):
if hotp(secret, current + i) == user_code:
return True
return False

Windows command to check system time sync:

w32tm /query /status
  1. From TOTP to WebAuthn: The Shift to Public‑Key Authentication

While TOTP improves security over SMS, it still relies on a shared secret stored on the server. A server breach can expose all TOTP seeds. WebAuthn (FIDO2) eliminates this by using public‑key cryptography:

  • User device generates a key pair
  • Private key never leaves the device
  • Server stores only the public key
  • Authentication uses a challenge signed by the private key

This aligns with the original observation: authentication becomes “can you compute a cryptographic function that only you can compute?”—now using asymmetric proofs instead of symmetric OTPs.

Example of generating a key pair with OpenSSL (conceptual):

 Generate private key
openssl ecparam -name prime256v1 -genkey -noout -out private.pem
 Extract public key
openssl ec -in private.pem -pubout -out public.pem

5. Hardening TOTP in Production Systems

When integrating TOTP, consider these security measures:

  • Rate limiting – prevent brute‑force of 6‑digit codes (1M attempts)
  • Secret encryption – store seeds encrypted at rest (AES‑256)
  • Secure enrollment – deliver secret via QR over TLS
  • Recovery codes – provide one‑time backup codes
  • Audit logging – record failed attempts and successful logins

Nginx rate‑limiting example:

limit_req_zone $binary_remote_addr zone=2fa:10m rate=5r/m;
location /verify {
limit_req zone=2fa burst=2 nodelay;
proxy_pass http://backend;
}

6. Command‑Line TOTP Generator (Linux Script)

Create a simple bash script using `oathtool` and `zenity` for GUI:

!/bin/bash
 totp_gui.sh
SECRET_FILE="$HOME/.totp_secrets.gpg"
 Decrypt secret (requires gpg agent)
SECRET=$(gpg -d "$SECRET_FILE" 2>/dev/null | grep "$1" | cut -d: -f2)
if [ -n "$SECRET" ]; then
CODE=$(oathtool --totp -b "$SECRET")
zenity --info --text="Your code: $CODE" --title="TOTP"
else
zenity --error --text="Secret not found"
fi

7. API Security with TOTP Verification

Modern APIs often use TOTP as a second factor. Here’s a Flask endpoint verifying a code:

from flask import Flask, request, jsonify
import pyotp

app = Flask(<strong>name</strong>)
USER_SECRETS = {"[email protected]": "JBSWY3DPEHPK3PXP"}

@app.route('/verify-2fa', methods=['POST'])
def verify_2fa():
data = request.get_json()
user = data.get('email')
user_code = data.get('code')
secret = USER_SECRETS.get(user)
if not secret:
return jsonify({"error": "User not found"}), 404
totp = pyotp.TOTP(secret)
if totp.verify(user_code, valid_window=1):
return jsonify({"success": True})
else:
return jsonify({"error": "Invalid code"}), 401

What Undercode Say

  • Mathematics replaces trust – TOTP demonstrates that cryptographic proofs can replace explicit trust between parties. The server doesn’t need to believe the user; it verifies computational capability.
  • Symmetric vs. asymmetric – While TOTP is elegant, WebAuthn’s public‑key model eliminates shared secrets, drastically reducing server‑side attack surface. The future belongs to hardware‑backed private keys.
  • Defense in depth – TOTP remains a powerful second factor when combined with proper rate limiting, encrypted storage, and phishing‑resistant delivery (avoid SMS). It teaches core principles applicable to broader system design.

Prediction

As passkeys and WebAuthn adoption accelerate, TOTP will gradually be relegated to legacy systems and backup authentication. However, the mathematical elegance of time‑based codes ensures they will remain a teaching cornerstone for cryptographers and backend engineers. The next wave will integrate biometrics with secure enclaves, making authentication both seamless and mathematically unforgeable.

▶️ Related Video (82% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Yaman Jain – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky