TL;DR
Google Authenticator QR codes don't contain encrypted data. They're plain text URLs with Base64-encoded Protocol Buffers data. After URL decoding, Base64 decoding, and protobuf parsing, you can recover the TOTP secret, account name, issuer, and algorithm. This is why one QR code is enough to restore 2FA on another device.
What Does a Google Authenticator QR Code Actually Contain?
Many people assume QR codes store encrypted secrets or binary images. The reality is simpler and more interesting: a Google Authenticator QR code contains only a plain text URL.
When you export accounts, Google generates a URL that looks like this:
otpauth-migration://offline?data=Cj4KFCRjm6rWzM/Vep5Ro7XFXaQY...If you scan this with a regular QR code scanner (not Authenticator), you'll see exactly this string. Nothing hidden, no images, no encryption layers at the surface level.
Breaking Down the URL Structure
This URL follows the otpauth:// standard, which is an RFC standard for TOTP. Like any URL, it has three parts:
- Scheme:
otpauth-migration://identifies this as an OTP migration URL - Path:
offlineindicates the data is self-contained (not fetched from a server) - Parameter:
data=...contains all the encoded account information
The real magic happens in that data parameter, which requires several decoding steps to unlock.
The Decoding Journey: From URL to Secret
Understanding how data is encoded is essential for security and privacy. Let's walk through each step.
Step 1: URL Decoding
URLs have reserved characters that cannot appear directly. Special characters are replaced with escape sequences like %2F for "/" or %3D for "=".
After URL decoding, you're left with a standard Base64 string ready for the next step.
Step 2: Base64 Decoding
Base64 is often mistaken for encryption. It's not. It's simply an encoding format that represents binary data as text using 64 safe characters (A-Z, a-z, 0-9, +, /).
When you decode Base64 with Google Authenticator data, you don't get readable text. Instead, you get binary data:
0A 3E 0A 14 24 63 9B AA D6 CC CF D5...This binary is not encrypted: it's just data in a different format. Anyone can decode it. For that reason, you should never share your exported QR code, and you should store backup codes securely.
Step 3: Protocol Buffers Parsing
This is where the structure emerges. Google uses Protocol Buffers (protobuf) to serialize the exported data.
Protocol Buffers is Google's binary serialization format. Compared to JSON or XML, it produces much smaller and faster data structures: critical for mobile authenticator apps.
The schema for Google Authenticator export roughly looks like this:
message OtpParameters {
bytes secret = 1;
string name = 2;
string issuer = 3;
Algorithm algorithm = 4;
DigitCount digits = 5;
OtpType type = 6;
}Using this schema, the protobuf parser knows that field 1 contains the secret, field 2 contains the account name, and so on. The parser then reconstructs the structured data.
What the Decoded Data Contains
After parsing the protobuf, you have a structured object with:
- Account name: example@example.com
- Issuer: Example (the service name)
- Secret: Binary data (24 63 9B AA D6 CC CF D5...)
- Algorithm: SHA1 or SHA256
- Digits: Usually 6 (the OTP code length)
- Type: TOTP (time-based) or HOTP (counter-based)
This is exactly what Authenticator needs to generate one-time codes. The binary secret is the core: it's what makes each 6-digit code unique and time-based.
Why Base32? The Human-Readable Secret
The secret inside the protobuf is raw binary. For humans, binary is inconvenient. That's why backup codes and manual entry fields use Base32 encoding.
Base32 converts the same binary data into readable text using 32 characters (A-Z and 2-7). For example:
ERRZXKWWZTH5K6U6KGR3LRK5UQMP3SXHThis is the same secret you see next to the QR code during 2FA setup. You can type it into almost any authenticator app. Base32 is also not encryption: it's just a different way to represent the same binary data.
Security Implications: Why This Matters for Privacy
Understanding how QR codes work is critical for privacy engineering. The key insight: there is no encryption at the QR level.
- QR codes are not encrypted: Anyone with your QR code can decode it and extract your TOTP secret. Treat exported QR codes as carefully as you would treat the secret itself.
- Transport matters: If you email or screenshot a QR code, you're transmitting an unencrypted secret. Use secure channels (encrypted messaging, in-person transfers) if you must share backup codes.
- Screenshots are permanent: Unlike viewing a QR code on a screen, screenshots can be backed up, synced to the cloud, or recovered from device storage. Enable screenshot blocking if possible.
- Base32 backups are equally sensitive: The Base32 backup code is just another representation of the same secret. Protect it the same way you would protect the QR code.
The Complete Transformation Process
Here's the full journey from QR code to usable secret:
QR Code (image)
↓
otpauth-migration://offline?data=...
↓
URL Decode
↓
Base64 Decode
↓
Binary Data (0A 3E 0A 14...)
↓
Protocol Buffers Parse
↓
Structured Data:
- Secret (binary)
- Account name
- Issuer
- Algorithm
- Digits
↓
Base32 Encode (optional)
↓
ERRZXKWWZTH5K6U6KGR3LRK5UQMP3SXHEach step is reversible and not encrypted. The only protection is obscurity and proper storage practices.
Why This Knowledge Matters
Understanding the mechanics of QR codes helps you:
- Make informed security decisions: Know that QR codes are not encrypted, so you'll treat them appropriately.
- Secure backup storage: Understand why you should never screenshot QR codes or email them unencrypted.
- Implement proper migration: When adding 2FA to new devices, use secure channels and verify codes before deleting old ones.
- Audit third-party tools: If you use backup or migration tools, you'll know to ask: do they decrypt the protobuf locally, or do they send it to their servers?
Conclusion
Google Authenticator QR codes are elegant but not encrypted. They contain plain-text URLs with encoded protobuf data. By decoding the URL, Base64, and protobuf, you can recover all necessary information to restore 2FA.
This is why a single exported QR code is enough to migrate to another device, and why you should treat exported codes with the same care you would treat the secrets themselves. For organizations implementing security, understanding these layers is essential for building a culture of proper 2FA practices.
The key takeaway: convenience and security are not mutually exclusive. Knowing how your authentication works empowers you to implement it responsibly.
