Migrate from Google Authenticator to password manager TOTP by adding TOTP secrets during account setup instead of using Google’s proprietary format. Password managers like Bitwarden, 1Password, and KeePass generate TOTP codes directly from stored secrets, provide automatic backups, and work across devices. This is more convenient than Google Authenticator (no manual entry needed) and more secure (tied to encrypted password vault rather than unencrypted device) while maintaining the same industry-standard TOTP algorithm.
Understanding TOTP Mechanics
TOTP generates temporary codes based on a shared secret and the current time. The algorithm follows RFC 6238 and produces 6-digit codes that expire every 30 seconds.
The core TOTP formula:
TOTP = HMAC-SHA1(secret, floor(current_unix_time / 30))
When you set up 2FA, the service provides a Base32-encoded secret. During authentication, both your device and the server generate codes using this secret and the same time window. If the codes match, authentication succeeds.
Why Migrate to Your Password Manager
Password managers that support TOTP offer several advantages over standalone authenticator apps:
Unified Storage: Your 2FA secrets live alongside your passwords, meaning one secure vault protects all your credentials. This eliminates the need to manage separate apps and reduces the attack surface.
Encrypted Backups: Unlike Google Authenticator’s lack of export options, password managers provide encrypted backups of your entire vault, including TOTP secrets.
Cross-Device Sync: Access your 2FA codes across desktop and mobile without manual transfer.
Search and Organization: Quickly find any 2FA code using your password manager’s search functionality rather than scrolling through a list of service icons.
Migrating from Google Authenticator
The migration process requires exporting your secrets from Google Authenticator and importing them into your password manager. Google Authenticator stores codes in QR codes or as manual entry keys.
Step 1: Export Your Google Authenticator Secrets
Open Google Authenticator and tap the three-dot menu. Select “Transfer accounts” then “Export accounts.” The app generates QR codes containing your secrets. Scan these with another device or decode them using tools like zbarimg:
# Install zbar tools
brew install zbar
# Decode QR code (if saved as image)
zbarimg google_auth_export.png
Alternatively, manually note the secret keys displayed in Google Authenticator during setup. Each entry shows the service name and the Base32 secret.
Step 2: Import into Your Password Manager
Most password managers support TOTP import via QR scanning or manual entry. For Bitwarden, for example:
- Open Bitwarden Vault
- Navigate to Options → Import
- Select “Google Authenticator (CSV)” as import source
- Upload your exported CSV file
For 1Password, scan the QR codes directly using the mobile app’s camera.
Using TOTP Programmatically
Developers often need to generate TOTP codes for automation or testing. The otpauth library provides straightforward implementation:
from otpauth import OtpAuth
# Initialize with your Base32 secret
totp = OtpAuth(secret="JBSWY3DPEHPK3PXP")
# Generate current TOTP code
code = totp.to_uri() # otpauth://totp/Example:secret?secret=...
print(f"Current code: {totp.generate()}")
For command-line TOTP generation, oathtool from the oath-toolkit package works well:
# Install oathtool
brew install oath-toolkit
# Generate TOTP from secret
oathtool --base32 --totp JBSWY3DPEHPK3PXP
This outputs a 6-digit code matching what your password manager displays.
Implementing TOTP in Your Applications
If you are building authentication systems, storing TOTP secrets requires careful handling:
import secrets
import base64
def generate_totp_secret():
"""Generate a secure random Base32 TOTP secret."""
return base64.b32encode(secrets.token_bytes(20)).decode('utf-8')
def verify_totp(secret, token):
"""Verify a TOTP token against a stored secret."""
from otpauth import OtpAuth
totp = OtpAuth(secret=secret)
return totp.verify(token, valid_window=1)
Store secrets in your database with encryption at rest. Never log or expose TOTP secrets in plaintext.
Security Considerations
While password managers with TOTP provide excellent convenience, consider these best practices:
Master Password Strength: Your master password protects all 2FA codes. Use a long, unique phrase with entropy exceeding 60 bits.
Enable Biometric Unlock: Most password managers support fingerprint or Face ID for quick access without compromising security.
Export Encrypted Backups: Regularly export an encrypted backup of your vault. Store this in a secure location separate from your primary device.
Use Hardware Security Keys for Critical Accounts: For high-value accounts (cryptocurrency, primary email), consider hardware keys like YubiKey over TOTP.
Troubleshooting Common Issues
Time Synchronization: TOTP requires accurate time on both device and server. If codes fail consistently, verify your system clock:
# Check time drift (macOS)
sudo sntp -s time.apple.com
Secret Key Format: Ensure you enter secrets in Base32 format. Some services display secrets in hexadecimal, requiring conversion.
Duplicate Entries: Some password managers create separate entries for passwords and TOTP. Verify your vault structure after import.
Advanced TOTP Implementation for Developers
For developers building applications that use TOTP for user authentication, understanding implementation details improves security.
Server-Side TOTP Verification
Implement strong TOTP verification that accounts for clock drift:
import hmac
import hashlib
import base64
import time
import struct
def verify_totp(secret, token, window=1):
"""
Verify TOTP token with time window tolerance.
window: Number of 30-second periods to accept
(0 = current period only, 1 = current ± 1 period)
"""
token = int(token)
secret_bytes = base64.b32decode(secret)
# Get current time counter
time_counter = int(time.time()) // 30
# Check token against multiple time windows
for i in range(-window, window + 1):
expected = hmac.new(
secret_bytes,
struct.pack('>Q', time_counter + i),
hashlib.sha1
).digest()
# Extract 31-bit integer from HMAC
offset = expected[-1] & 0xf
code = struct.unpack('>I', expected[offset:offset+4])[0] & 0x7fffffff
code = code % 1000000
if code == token:
return True
return False
This implementation handles:
- Users with clocks slightly out of sync (window=1 allows ±30 seconds)
- Proper HMAC-SHA1 generation per RFC 6238
- Return code validation
Backup Codes for Account Recovery
When users store TOTP in a password manager, they must have recovery mechanisms if their vault is inaccessible:
import secrets
def generate_backup_codes(count=8):
"""Generate backup codes for TOTP recovery."""
codes = []
for _ in range(count):
# 8 alphanumeric characters per code
code = secrets.token_urlsafe(6)[:8].upper()
codes.append(code)
return codes
def hash_backup_code(code):
"""Hash backup code for storage (like passwords)."""
import hashlib
return hashlib.sha256(code.encode()).hexdigest()
Generate backup codes during TOTP setup. Users save them offline (printed, encrypted file) for emergency use.
Database Schema for TOTP Storage
Store TOTP secrets securely at the application level:
CREATE TABLE user_totp_credentials (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL UNIQUE REFERENCES users(id),
secret VARCHAR(32) NOT NULL,
backup_codes_hash TEXT[] NOT NULL,
enabled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_used_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Separate table for backup code tracking
CREATE TABLE backup_code_usage (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id),
code_hash VARCHAR(64) NOT NULL,
used_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Never store backup codes in plaintext. Hash them using bcrypt or similar, similar to password storage.
TOTP Setup Flow Best Practices
- Generate secret on server, don’t trust client-generated secrets
- Display secret in Base32 and QR code for user to scan
- Require test token before enabling (user provides one generated token to verify)
- Display backup codes only once, clearly warn to save offline
- Enforce backup code save before enabling TOTP
def setup_totp_for_user(user_id):
# Generate 32-byte secret (256 bits)
secret = base64.b32encode(secrets.token_bytes(32)).decode('utf-8')
# Generate backup codes
backup_codes = generate_backup_codes(10)
# Create QR code for easy scanning
totp_uri = f"otpauth://totp/{user_id}?secret={secret}&issuer=YourApp"
return {
'secret': secret,
'qr_code_uri': totp_uri,
'backup_codes': backup_codes, # Show ONCE, then hash for storage
'backup_codes_hash': [hash_backup_code(c) for c in backup_codes]
}
Migration from Authenticator Apps
When users migrate from Google Authenticator or Authy:
def export_totp_for_migration(user_id):
"""Generate portable TOTP export for user."""
user_secrets = get_user_totp_secrets(user_id)
export_data = {
'version': 1,
'date': datetime.now().isoformat(),
'secrets': [
{
'account': secret.account_name,
'secret': secret.base32_secret,
'issuer': secret.issuer,
'algorithm': 'SHA1'
}
for secret in user_secrets
]
}
# Encrypt for safety
encrypted = encrypt_export(export_data)
return encrypted
Comparison: Password Manager TOTP vs Dedicated Authenticators
| Aspect | Password Manager | Google Authenticator | Authy | Hardware Key |
|---|---|---|---|---|
| Cost | Free (with manager) | Free | Free | $40-80 |
| Backup/Sync | Automatic (encrypted) | No automatic backup | Cloud sync (optional) | Manual backup |
| Search | Yes | No (icon-based) | Yes | N/A |
| Recovery Codes | Easy access | Manual tracking | Manual tracking | Printed codes |
| Account Recovery | Master password | Difficult | Account recovery | Recovery codes only |
| Phishing Resistant | No | No | No | Yes (FIDO2) |
Password managers excel at convenience and organization. Hardware keys (YubiKey with FIDO2 protocol) provide maximum security but lack TOTP generation. Dedicated authenticators offer a middle ground with cloud sync options.
Use Case Recommendations
Use password manager TOTP for:
- User accounts you access regularly
- Services where convenience matters
- Development/test environments
- Accounts without high monetary value
Use hardware keys for:
- Primary email account
- Cryptocurrency wallets
- Financial institutions
- Administrative accounts
Use dedicated authenticators for:
- Personal accounts where backup/sync matters
- Accounts shared between devices you don’t sync passwords across
TOTP at Scale: Enterprise Implementation
Organizations deploying TOTP should implement:
class EnterpriseOTPPolicy:
def __init__(self):
self.min_setup_time = 72 # Hours to set up after enabling
self.rate_limit = 5 # Failed attempts per minute
self.backup_code_count = 10
self.window_size = 1 # Accept ±1 time window
self.algorithm = 'SHA1'
def enforce_totp_setup(self, user):
"""Require TOTP for users with elevated privileges."""
if user.is_admin or user.has_access_to_sensitive_systems:
if not user.totp_enabled:
user.totp_setup_deadline = datetime.now() + timedelta(days=3)
user.totp_enforcement = True
Enforce TOTP for:
- Administrative accounts
- Users with access to production systems
- Finance/accounting personnel
- Security-sensitive roles
Related Articles
- Best Password Manager CLI Tools: A Developer’s Guide
- Best Password Manager for Android 2026: A Developer’s Guide
- Best Password Manager for Developers: A Technical Guide
- Best Password Manager for Enterprise: A Technical Guide
- Best Password Manager For Firefox Extension
Built by theluckystrike — More at zovo.one