ProtonMail Two-Factor Authentication Guide
To enable two-factor authentication on ProtonMail, go to Settings, then Security, click “Enable 2FA,” scan the QR code with an authenticator app like Aegis or Authy, and enter the 6-digit code to confirm. ProtonMail supports both TOTP (authenticator app codes) and WebAuthn/FIDO2 (hardware security keys like YubiKey)–TOTP is the fastest to set up, while WebAuthn provides stronger phishing resistance. This guide walks through both methods along with recovery strategies and developer integration patterns.
Understanding ProtonMail’s 2FA Options
ProtonMail supports two primary authentication methods:
- TOTP (Time-based One-Time Password) — Generated by authenticator apps like Aegis, Authy, or Google Authenticator
- WebAuthn/FIDO2 — Hardware security keys like YubiKey or Titan
TOTP works offline and gives you control over where your secrets are stored. WebAuthn provides phishing resistance but requires physical hardware.
For developers building applications that integrate with ProtonMail, understanding these options helps when designing authentication flows for users who prioritize security.
Setting Up TOTP-Based 2FA
Step 1: Access Security Settings
Log into your ProtonMail account and navigate to Settings → Security. You’ll find the two-factor authentication section near the bottom of the page.
Step 2: Generate Your Secret
Click “Enable 2FA” to generate a TOTP secret. ProtonMail displays a QR code and the raw secret as a Base32 string:
JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP
Step 3: Configure Your Authenticator
For developers who prefer command-line tools, you can generate TOTP codes manually using standard libraries:
Python example using pyotp:
import pyotp
# The secret from ProtonMail settings
secret = "JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP"
# Generate current TOTP code
totp = pyotp.TOTP(secret)
current_code = totp.now()
print(f"Your 2FA code: {current_code}")
Node.js example:
const TOTP = require('totp-generator');
const secret = 'JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP';
const token = TOTP.generate(secret);
console.log(`Your 2FA code: ${token}`);
Step 4: Verify and Activate
Enter the 6-digit code from your authenticator app to complete setup. ProtonMail displays a set of recovery codes—store these securely, preferably in a password manager.
Setting Up WebAuthn Security Keys
Hardware security keys provide stronger protection against phishing. To set this up in ProtonMail:
- Go to Settings → Security
- Select “Add a security key” under WebAuthn
- Insert your YubiKey and touch the sensor
- Name your key (e.g., “YubiKey Work”)
ProtonMail supports multiple keys, which is useful for redundancy.
Automating 2FA with ProtonMail API
For developers building tools that interact with ProtonMail, understanding the authentication flow is essential. ProtonMail’s API uses OAuth 2.0, and 2FA adds an additional verification step.
Here’s how you might handle 2FA in a Python script using the ProtonMail API:
import requests
def authenticate_with_2fa(username, password, two_factor_code):
# Step 1: Obtain authentication challenge
auth_url = "https://api.protonmail.ch/auth"
initial_response = requests.post(auth_url, data={
"Username": username,
"Password": password
})
# Step 2: Submit 2FA code
session_token = initial_response.json()["Token"]
twofa_payload = {
"two_factor_code": two_factor_code,
"token": session_token
}
verify_response = requests.post(
f"{auth_url}/2fa",
json=twofa_payload
)
return verify_response.json()["access_token"]
Recovery Strategies
2FA introduces a single point of failure—losing access to your authentication device can lock you out permanently. ProtonMail provides several recovery mechanisms:
Recovery Codes
ProtonMail generates 10 single-use recovery codes during 2FA setup. Each code works once and cannot be regenerated. Best practices:
- Store at least one code offline (printed, stored in a safe)
- Distribute codes across multiple locations
- Use a dedicated password manager entry
Secondary Email
Add a secondary email address in Settings → Security → Recovery. This provides a fallback verification method.
PGP Key Recovery
If you use PGP encryption with ProtonMail, your private key can serve as an additional recovery mechanism. Export your key and store it securely:
# Export your PGP private key (from your local GPG keyring)
gpg --armor --export-secret-keys your@email.com > private_key.asc
Security Considerations for Developers
When building applications that handle ProtonMail credentials or 2FA tokens, follow these practices:
- Never store plaintext passwords — Use proper hashing (Argon2, bcrypt)
- Encrypt 2FA secrets at rest — TOTP secrets are sensitive data
- Implement rate limiting — Protect against brute-force attacks on 2FA codes
- Use secure memory handling — Clear sensitive data from memory after use
Example of secure secret storage in Python:
from cryptography.fernet import Fernet
import os
# Generate encryption key (store this securely!)
key = Fernet.generate_key()
cipher = Fernet(key)
# Encrypt TOTP secret before storage
secret = "JBSWY3DPEHPK3PXP..."
encrypted_secret = cipher.encrypt(secret.encode())
# Store encrypted_secret in your database
Common Pitfalls
- Losing recovery codes — Always print and store them
- Changing phones without transferring authenticator — Export your TOTP secrets before switching devices
- Using SMS 2FA — ProtonMail doesn’t support SMS, which is fortunate since SIM swapping attacks are common
Conclusion
Two-factor authentication significantly strengthens your ProtonMail security posture. For most users, TOTP provides an excellent balance of security and convenience. Developers and power users may prefer WebAuthn for its phishing resistance or integrate programmatic 2FA into their workflows using the approaches outlined here.
Remember that 2FA is just one layer of defense—use strong, unique passwords, keep your recovery information updated, and regularly audit your active sessions.
Related Reading
- Bitwarden Vault Export Backup Guide: Complete Technical.
- VPN Warrant Canary: What It Means and Why It Matters
- Best VPN for Linux Desktop: A Developer Guide
Built by theluckystrike — More at zovo.one