TOTP Backup Codes and Recovery
Implement TOTP backup codes for account recovery when users lose their authenticator device. Learn generation methods, secure storage, and UX best practices for recovery flows.
Detailed Explanation
TOTP Backup Codes: Preventing Account Lockout
Backup codes (also called recovery codes) are one-time-use codes that allow users to access their account when they cannot generate a TOTP code — typically because they have lost their phone or uninstalled their authenticator app.
Why Backup Codes Are Essential
Without backup codes, a user who loses access to their authenticator has no way to log in. This creates one of the worst user experience scenarios in authentication:
- Device loss: phone stolen, broken, or factory reset
- App deletion: accidentally uninstalling the authenticator
- Device migration: getting a new phone without exporting TOTP accounts
- App malfunction: authenticator app data corruption
Generating Backup Codes
Backup codes should be:
- Cryptographically random: use a CSPRNG, not sequential numbers
- Sufficiently long: 8-10 alphanumeric characters per code
- Unique per user: never share codes between accounts
- Provided in sets: typically 8-10 codes per generation
import secrets
import string
def generate_backup_codes(count=10, length=8):
alphabet = string.ascii_lowercase + string.digits
codes = []
for _ in range(count):
code = ''.join(secrets.choice(alphabet) for _ in range(length))
# Format as xxxx-xxxx for readability
codes.append(f"{code[:4]}-{code[4:]}")
return codes
Storage and Security
On the server side:
- Hash each code (bcrypt or SHA-256 with salt) before storing
- Mark codes as used after redemption — they are single-use
- Store the hash, not the plaintext — treat backup codes like passwords
- Allow regeneration — users should be able to invalidate old codes and get new ones
User Experience Best Practices
- Display once: show codes immediately after 2FA enrollment, clearly stating they will not be shown again
- Download option: provide a "Download as text file" button
- Copy button: one-click copy all codes to clipboard
- Confirmation: require the user to confirm they have saved the codes before proceeding
- Count display: show remaining unused codes on the security settings page
- Regeneration: allow users to generate a new set (invalidating the old ones)
Recovery Flow
When a user attempts to log in without their authenticator:
- Present a "Lost your device?" or "Use backup code" option
- Accept a backup code in place of the TOTP code
- Mark that backup code as consumed
- After login, strongly encourage re-enrollment with a new device
- Consider requiring password verification alongside the backup code
Use Case
Product and security teams implementing a complete 2FA system must include backup codes to prevent account lockout. This guide covers the full lifecycle — generation, presentation, secure storage, and redemption — ensuring users always have a recovery path. It is especially critical when planning for customer support load reduction, as proper backup code implementation dramatically reduces 'locked out of my account' support tickets.