Коротко
При экспорте аккаунтов Google Authenticator создается QR код, который содержит обычную текстовую строку. Внутри неё хранится не изображение и не зашифрованный секрет, а сериализованные данные в формате Protocol Buffers, закодированные в Base64. После нескольких этапов декодирования можно получить секрет TOTP, название аккаунта, издателя и алгоритм. Именно поэтому один QR код позволяет полностью восстановить 2FA на новом устройстве.
Что содержит QR код Google Authenticator
Многие считают, что QR код Google Authenticator хранит какое-то изображение или зашифрованный текст.
На самом деле QR код представляет собой обычную строку.
При экспорте аккаунтов она выглядит примерно так:
otpauth-migration://offline?data=Cj4KFCRjm6rWzM/Vep5Ro7XFXaQY...Именно эта строка кодируется в QR код.
Если считать QR код обычным сканером, получится именно такой текст.
Пример строки экспорта
Разберем её по частям.
otpauth-migration://offline?data=Cj4KFCRjm6rWzM/Vep5Ro7XFXaQY...Здесь можно выделить три основные части:
- Схема (Scheme):
otpauth-migration:// - Путь (Path):
offline - Параметр:
data=...
Именно параметр data содержит всю информацию о ваших аккаунтах.
Путь декодирования: шаг за шагом
Шаг 1: Разбор URL
Любой URL имеет определенную структуру. В нашем примере:
Scheme: otpauth-migration:// Path: offline Parameter: data=Cj4KFCRjm6rWzM/Vep5Ro7XFXaQY...
Нас интересует только значение параметра data.
Шаг 2: URL Decode
Некоторые символы нельзя использовать напрямую внутри URL. Поэтому они заменяются специальными последовательностями.
Например:
%2F → /
%2B → +
%3D → =После URL Decode получается обычная строка Base64.
Шаг 3: Base64 Decode
Base64 часто принимают за шифрование. На самом деле это обычное кодирование данных.
Например:
Hello
↓
SGVsbG8=Любой может выполнить обратное преобразование и получить исходный текст.
В Google Authenticator после декодирования Base64 получается уже не текст, а бинарные данные:
0A 3E 0A 14 24 63 9B AA D6 CC ...На этом этапе человеку прочитать информацию уже невозможно.
Шаг 4: Protocol Buffers
Именно здесь начинается настоящая структура данных. Google использует собственный бинарный формат сериализации под названием Protocol Buffers (protobuf).
Он был разработан Google для компактного хранения структурированных данных. По сравнению с JSON он занимает значительно меньше места и быстрее обрабатывается.
Как Google понимает структуру данных
Protocol Buffers работает по заранее известной схеме. Для Google Authenticator она выглядит примерно так:
message OtpParameters {
bytes secret = 1;
string name = 2;
string issuer = 3;
Algorithm algorithm = 4;
DigitCount digits = 5;
OtpType type = 6;
}Это означает:
- поле №1 содержит секрет;
- поле №2 содержит имя аккаунта;
- поле №3 содержит название сервиса;
- поле №4 содержит алгоритм;
- поле №5 содержит количество цифр;
- поле №6 содержит тип OTP.
Парсер Protocol Buffers читает бинарные данные и автоматически понимает, что означает каждое поле.
После декодирования получается обычная структура
Например:
Account: example@example.com Issuer: Example Secret: 24 63 9B AA D6 CC ... Algorithm: SHA1 Digits: 6 Type: TOTP
Именно эту информацию затем использует Google Authenticator.
Почему секрет хранится как бинарные данные
Внутри Protocol Buffers секрет представляет собой обычный массив байтов.
Например:
24 63 9B AA D6 CC CF D5 ...Такой формат очень удобен для программ, но совершенно неудобен для человека.
Поэтому используется ещё одно преобразование.
Что такое Base32
Base32 представляет бинарные данные в виде текста.
Например:
24 63 9B AA D6 CC ... ↓ ERRZXKWWZTH5K6U6KGR3LRK5UQMP3SXH
Именно такой секрет обычно показывают сайты рядом с QR кодом.
Его можно вручную добавить практически в любой аутентификатор.
Почему Base32 не является шифрованием
Base32 не скрывает информацию. Это лишь другой способ записи тех же самых данных.
Процесс выглядит так:
Бинарные данные ↓ Base32 ↓ ERRZXKWWZTH5K6U6KGR3LRK5UQMP3SXH
Любой может выполнить обратное преобразование и получить исходные байты.
Поэтому Base32 относится к кодированию, а не к шифрованию.
Полная цепочка преобразований
Весь процесс можно представить следующим образом:
QR Code ↓ otpauth-migration://offline?data=... ↓ URL Decode ↓ Base64 Decode ↓ Protocol Buffers Decode ↓ Secret Account Issuer Algorithm Digits Type ↓ Base32 ↓ Универсальный TOTP Secret
Почему это важно для безопасности
QR код Google Authenticator не содержит изображение или зашифрованный секрет.
Он содержит обычную строку URL, внутри которой находится сериализованная структура данных. После последовательного выполнения URL Decode, Base64 Decode и разбора Protocol Buffers можно получить всю информацию, необходимую для восстановления аккаунта.
Это означает, что QR коды не защищены криптографией на уровне самого QR. Вся защита основана только на том, что код хранится в безопасности.
- QR коды не зашифрованы: Любой, у кого есть ваш QR код, может получить ваш TOTP-секрет.
- Транспорт имеет значение: Не отправляйте QR коды по незащищённым каналам.
- Скриншоты постоянны: Они могут синхронизироваться в облако или восстанавливаться из памяти устройства.
- Base32 не является шифрованием: Резервная копия в Base32 это то же самое, что QR код.
Заключение
QR код Google Authenticator не содержит изображение или зашифрованный секрет.
Он содержит обычную строку URL, внутри которой находится сериализованная структура данных.
После последовательного выполнения URL Decode, Base64 Decode и разбора Protocol Buffers можно получить всю информацию, необходимую для восстановления аккаунта.
Именно поэтому один QR код позволяет полностью восстановить двухфакторную аутентификацию на новом устройстве, а секрет в формате Base32 можно использовать как универсальную резервную копию, совместимую практически со всеми приложениями для работы с TOTP.
Для организаций, внедряющих безопасность, понимание этих слоёв необходимо для создания культуры надлежащей практики 2FA.
