Meta 1 мая показала как они хранят ключи от ваших бэкапов WhatsApp. Разбираю архитектуру и сравниваю

от автора

Дисклеймер: в статье несколько раз упомянут мой собственный мессенджер ONEMIX. Если такое триггерит — закройте сейчас, не обижусь. Если интересно как решают одну и ту же инженерную задачу в Meta и в команде из одного человека, поехали.

Первого мая на Engineering at Meta вышел пост «How Meta Is Strengthening End-to-End Encrypted Backups». Одиннадцатого мая продолжение про Labyrinth 1.1, реализацию для Android. Я прочитал оба, потом полез в whitepaper, потом сравнил с тем что делаю у себя, и решил написать разбор. Не пересказ маркетингового материала, а нормальный технический разбор. Что они сделали, почему именно так, где у меня болело по дороге, какие компромиссы они выбрали, какие выбрал я.

Сразу важная оговорка про что эта статья. Она не про шифрование сообщений в транзите. Signal Protocol, Double Ratchet, X3DH — всё это давно стандарт, все нормальные мессенджеры это используют. WhatsApp лицензировал Signal Protocol ещё в 2016-м. Транзит решённая задача.

Эта статья про следующее звено цепи, которое для большинства пользователей до сих пор сломано. Про бэкапы.

Где была дырка

Представьте картину. Вы пишете сообщение в WhatsApp. Оно шифруется на вашем телефоне ключом, который никто кроме адресата не знает. Долетает до сервера WhatsApp в зашифрованном виде, сервер не может его прочесть. Перелетает на устройство адресата, расшифровывается там. Всё работает с 2016 года.

Дальше история становится менее красивой. Раз в сутки ваш WhatsApp делает бэкап чатов в iCloud (на iPhone) или Google Drive (на Android). И до недавнего времени этот бэкап лежал у Apple или Google в открытом виде. То есть Apple физически могла его прочитать. Google тоже могла. По запросу спецслужб любой страны эти бэкапы выдавались. Несколько громких уголовных дел в США закрывали именно так: подозреваемый общался в WhatsApp, обвинение получало бэкап из iCloud.

Получалось что E2E в мессенджере был, а на уровне всей системы не было. Потому что один из двух собеседников почти наверняка делает бэкап в облако, и через этот бэкап доступ ко всей переписке получает третья сторона.

В 2021 году Meta сделала первый заход и добавила E2E для бэкапов. Тогда же я впервые прочитал их whitepaper и подумал что у них там какие-то странные ребята, половину деталей оставили на потом, ключевой компонент (HSM-флот) описан в три абзаца, ничего не понятно. Пять лет ждал нормального разбора.

Дождался. В мае 2026-го Meta опубликовала наконец полную картину и заодно сделала следующий шаг: over-the-air распространение публичных ключей флота и независимая аудируемость через Cloudflare. Идём разбираться.

Базовая модель угроз

Прежде чем лезть в архитектуру, нужно понять что именно мы защищаем. От кого защищаем отдельный вопрос, и тут есть несколько ролей.

Сам пользователь. Он хочет иметь доступ к своему бэкапу после смены устройства. Если он забыл пароль, должен быть способ восстановить. Но восстановление не должно быть таким простым чтобы им мог воспользоваться кто-то другой.

Облачный провайдер. Apple iCloud, Google Drive. Они хранят зашифрованный блоб бэкапа физически. Угроза от них в том что они могут попытаться расшифровать. Если у них в руках только зашифрованный блоб без ключа, они бессильны.

Сама Meta. Ключевая роль во всей конструкции. Meta управляет инфраструктурой проверки ключей. Если архитектура построена так, что Meta может одна, без участия пользователя, восстановить ключ, значит Meta может всё. Это плохая модель. Хорошая модель: Meta управляет инфраструктурой, но даже сама не может расшифровать без знания пароля пользователя.

Государство. Самая неудобная роль для проектировщика системы. Государство может прийти к Meta с ордером и потребовать выдать ключ. Если Meta может выдать, значит выдаст рано или поздно. Если Meta физически не может, требование становится бессмысленным.

Внутренний инсайдер. Сотрудник Meta с админскими правами. Может ли он один украсть ключи? Может ли группа из нескольких? Этот вектор всегда недооценивают.

Цель архитектуры построить систему, в которой ключ бэкапа знают только две стороны: пользователь и HSM-флот. Причём HSM-флот должен быть устроен так, что даже сама Meta как организация не может его заставить выдать ключ без участия пользователя.

Сделать такую систему сложно. Meta построила её на трёх компонентах: HSM-флот как распределённый кворум, протокол OPAQUE для регистрации и проверки пароля без раскрытия, и независимый аудит через Cloudflare. Дальше по каждому компоненту.

HSM-флот: почему один не годится

HSM это Hardware Security Module. Железяка, которая внутри умеет хранить криптографические ключи и выполнять операции с ними, но не отдаёт ключи наружу никогда. Даже физический доступ к плате не даёт прочитать ключ. Внутри обычно есть антитамперинг: если попытаться вскрыть, ключи самоуничтожатся.

Один HSM сильно, но недостаточно. Есть несколько проблем. Первая, HSM может физически сломаться. Если в нём сидит ключ от бэкапа десятка миллионов человек и он сгорел, это очень плохой день. Вторая, один HSM это одна точка отказа и одна точка взлома. Если кто-то получит физический доступ и каким-то экзотическим способом снимет ключи (теоретически возможно через побочные каналы, термическую атаку и так далее), он получит всё.

Поэтому Meta использует не один HSM, а флот. Географически распределённый по нескольким дата-центрам. Реплицируется операция по majority-consensus, то есть для подтверждения операции нужно согласие большинства узлов флота. Это даёт две гарантии. Отказ нескольких узлов не валит сервис. И чтобы взломать ключ, надо одновременно скомпрометировать большинство географически разнесённых узлов, что несоизмеримо сложнее чем один.

Каждый узел флота имеет свою пару ключей. Публичная часть пары используется клиентом WhatsApp для установки защищённой сессии. Приватная часть никогда не покидает HSM.

Здесь возникает закономерный вопрос. Как клиент WhatsApp знает что он разговаривает именно с легитимным HSM-флотом Meta, а не с подставным сервером? В WhatsApp это решено лобовым способом: публичные ключи флота захардкожены в код приложения. Обновили флот, обновили приложение, выпустили апдейт через стор. Работает.

Но для Messenger такой подход не подошёл. Messenger меняет флоты HSM чаще, чем выпускаются апдейты приложения. Поэтому в мае 2026 Meta представила механизм OTA-распространения публичных ключей флота. И вот тут вступает Cloudflare.

Cloudflare как независимый свидетель

Когда клиент Messenger подключается к HSM-флоту, флот возвращает свой публичный ключ в составе так называемого validation bundle. Этот bundle подписан Cloudflare и контрсайнен самой Meta.

Зачем тут Cloudflare. Если бы bundle подписывала только Meta, то Meta могла бы по своему желанию выпустить bundle с подставным ключом и подсунуть его пользователю. Пользователь установил бы защищённую сессию с подставным HSM, который на самом деле принадлежит Meta или государству, и слил бы свой пароль.

Cloudflare в этой схеме играет роль независимого свидетеля. Она независимо валидирует что ключ принадлежит легитимному развёртыванию, подписывает bundle и ведёт публичный audit log всех выпущенных bundle. Любой исследователь может зайти и проверить какие именно ключи были выпущены и не было ли подмены.

Архитектурный приём здесь любопытный. Он не делает Meta доверенной стороной. Он добавляет вторую сторону, у которой нет особых причин сговориться с Meta для подмены. Аудит лог открыт, любой может смотреть, подмена будет видна.

Слабое место у схемы тоже есть, и это сама Cloudflare. Если Cloudflare скомпрометируют или принудят к сотрудничеству, всё ломается. Cloudflare американская компания, и в случае национальной безопасности она тоже подчиняется тем же субпоенам что и Meta. То есть архитектура защищает от обычного гражданского запроса и от ситуации когда Meta хочет подсмотреть. От FISA-warrant она защищает уже не до конца.

OPAQUE: пароль которого никто не знает

Самая красивая часть всей системы.

Задача такая. Пользователь хочет защитить свой бэкап паролем. Пароль он будет помнить в голове. При восстановлении на новом устройстве он введёт пароль и должен получить ключ от бэкапа. Сервер должен проверить что пароль правильный.

Простое решение: сервер хранит хеш пароля, при вводе сравнивает, если совпало, выдаёт ключ. Плохое решение. Если сервер скомпрометирован, утечёт хеш, и его можно брутфорсить оффлайн. Если сервер недобросовестный, он может однажды просто отдать ключ без проверки.

OPAQUE решает обе проблемы. Это асимметричный протокол парольной аутентификации, разработанный в академии в 2018 году и стандартизированный IETF в 2024. Идея простая на пальцах. Пользователь и сервер выполняют криптографический обмен, в результате которого сервер математически проверяет знание пользователем пароля, но сам пароль никогда не видит и не хранит. Даже хеш не хранит в обычном смысле.

В архитектуре Meta это работает так. При первичной настройке бэкапа клиент генерирует 256-битный ключ через CSPRNG. Этот ключ нужно где-то сохранить так, чтобы потом можно было восстановить только через знание пароля. Клиент запускает OPAQUE-регистрацию с HSM-флотом: вводится пароль, генерируются эфемерные значения, в HSM сохраняется специальная запись, привязанная к устройству. Сам пароль уходит в небытие, клиент его не передаёт открыто, HSM не видит.

При восстановлении на новом устройстве запускается OPAQUE-аутентификация. Клиент доказывает HSM знание пароля без раскрытия. HSM убеждается в правильности доказательства и выдаёт ключ. Если пароль неправильный, доказательство не сходится, ключ не выдаётся. Брутфорсить по сети нельзя, потому что HSM считает попытки и блокирует.

Дальше нюанс. Даже если кто-то получит полный дамп памяти HSM (что почти невозможно, но допустим), он не получит из него пароля и не сможет восстановить ключи без проведения OPAQUE-обмена с легитимной парой ключей. Атакующий получит мёртвый материал, из которого без знания пароля ничего не вытащишь.

OPAQUE, на мой вкус, одна из самых красивых вещей в прикладной криптографии последних десяти лет. Если хочется глубже, оригинальная статья называется «OPAQUE: An Asymmetric PAKE Protocol Secure Against Pre-Computation Attacks», авторы Jarecki, Krawczyk, Xu, 2018 год. Стандартизация RFC 9807, август 2024.

Что Meta не показала

Критическая часть. Без неё это пресс-релиз, а не разбор.

Первое. Whitepaper описывает протокол, но не описывает физическую безопасность дата-центров где стоят HSM. Это понятно, такая информация закрытая и должна оставаться закрытой. Но это означает что внутренний инсайдер с физическим доступом всё-таки потенциально может что-то сделать. Сколько человек могут пройти к HSM, какие там процедуры разделения обязанностей, мы не знаем.

Второе. Cloudflare как точка независимости работает только если Cloudflare действительно независима. Если завтра окажется что у CEO Meta и CEO Cloudflare есть приватные договорённости, или обе компании одновременно получат секретный приказ от FBI, схема не сработает. Это неустранимая слабость любой архитектуры с двумя американскими корпорациями.

Третье. Модель «пароль защищает ключ» имеет фундаментальный потолок. Если пользователь поставит пароль «1234», никакая криптография ему не поможет. HSM конечно блокирует брутфорс по сети, но если пароль слабый и атакующий каким-то образом получил оффлайн-копию OPAQUE-записи (через инсайдера, через эксплойт в HSM), он может попробовать словарь. Защита здесь больше про процедурные ограничения чем про криптостойкость.

Четвёртое, и это даже не критика. Архитектура Meta очень дорогая. HSM-флоты в нескольких дата-центрах, интеграция с Cloudflare, аудиты, whitepaper, постоянная команда криптографов. Это всё стоит десятков миллионов долларов в год. Для крупной корпорации с миллиардом пользователей окупается. Для соло-разработчика или маленькой команды нерешаемо в лоб.

Вот к этому моменту имеет смысл перейти к тому как ту же задачу решаю я.

Как это устроено в ONEMIX

Несколько вводных. ONEMIX это мессенджер который я пишу как соло-разработчик. React Native клиент, FastAPI бэкенд, E2E через Double Ratchet, голосовые и видеозвонки через WebRTC плюс LiveKit. Я не Meta. У меня нет миллионов долларов на HSM-флоты в Чикаго, Дублине и Сингапуре с majority-consensus replication. У меня есть один арендованный сервер и в перспективе один физический сервер в России.

Поэтому моя архитектура бэкапов строится на другом базовом принципе. Не «мы хорошо защищаем серверный ключ», а «у нас нет серверного ключа». Это называется server-blind architecture, и компромиссы там ровно противоположные.

Конкретно. Бэкап шифруется на устройстве пользователя 256-битным ключом, сгенерированным локально. Ключ никуда не отправляется. Совсем никуда: ни на сервер, ни в третью сторону. Шифрованный блоб бэкапа уходит на сервер без ключа. Сервер видит только зашифрованную кучу байт и физически не может с ней ничего сделать.

Восстановление работает через recovery phrase. 24 слова BIP-39, как в криптокошельках. Пользователь сохраняет себе эту фразу при первой настройке. На новом устройстве вводит её обратно, из неё через PBKDF2 + HKDF получается тот же 256-битный ключ, которым расшифровывается бэкап с сервера.

У подхода есть очевидное преимущество и не менее очевидный недостаток. С преимуществом всё ясно: я как оператор сервиса не могу прочитать ничьи сообщения, потому что у меня нет ничего что можно было бы пытать. Государство не может прийти ко мне с ордером и потребовать выдать ключи. Мне нечего выдавать. OPAQUE-протокол не нужен, потому что нечего проверять. HSM не нужен, потому что нечего хранить.

Недостаток в том, что если пользователь потерял recovery phrase, всё. Никакого восстановления через секретный вопрос, никакого «забыли пароль, ответьте про девичью фамилию матери», никакого реквеста в саппорт. Чаты умерли вместе с фразой.

Так задумано. У Meta выбран один компромисс: пользователь может восстановиться через пароль, но цена этого сложная инфраструктура из HSM и Cloudflare плюс неустранимое теоретическое доверие к американской юрисдикции. У меня выбран другой: пользователь сам отвечает за свои ключи, но взамен получает реальную, не зависящую от моего поведения, гарантию приватности.

Какой подход правильнее, зависит от модели угроз пользователя. Для миллиарда обычных людей которые путают пароль от почты с PIN-кодом от карты, подход Meta лучше. Они физически не управятся с recovery phrase. Для аудитории которой нужна максимальная гарантия, подход ONEMIX лучше, потому что там нет третьей стороны которой нужно доверять.

Я честно говорю обоим типам пользователей: если вам нужен мессенджер для обычной жизни с быстрым восстановлением, оставайтесь в WhatsApp, у них хорошо. Если нужен мессенджер для разговоров которые точно не должны попасть в чужие руки, и вы готовы сами хранить 24 слова, onemix.me.

Что из этого можно унести домой

Я выписал для себя несколько технических наблюдений после чтения whitepapers и сравнения со своим кодом.

OPAQUE стоит внимания. Если вы строите любую систему где пользователь должен иметь возможность восстановить какой-то секрет через пароль, и при этом сервер не должен видеть пароль, посмотрите на OPAQUE. RFC 9807 короткий, libopaque есть для нескольких языков. Я для своих внутренних кейсов планирую интегрировать его в админку, чтобы перестать хранить хеши паролей от админок целиком.

Архитектура с независимым свидетелем через Cloudflare сильный приём. Cloudflare изначально не претендует на роль независимой сертифицирующей стороны, но фактически становится ей. Этот паттерн можно использовать в любой системе где две стороны не доверяют друг другу полностью. Добавьте третью сторону у которой нет интереса сговариваться, и схема становится сильно крепче. Я думаю про похожее для своего сервера ключей — пока не реализовано, но направление понятное.

HSM не только для финтеха. В моей картине мира HSM до недавнего времени ассоциировались только с банковским процессингом и сертификатными центрами. Meta показывает что для мессенджеров с миллиардом пользователей это тоже разумный компромисс. Для меньших масштабов есть software-HSM, например SoftHSM, который даёт часть тех же гарантий без капитальных затрат на железо.

Server-blind как альтернатива. Если вы можете позволить себе сказать пользователю «храни свой recovery phrase сам», можно построить систему которая фундаментально проще и фундаментально безопаснее любого HSM-flow. Подходит не всем. Bitcoin, MetaMask, Session устроены именно так.

И главное. E2E в транзите без E2E в бэкапе это половина решения. Если у вас Double Ratchet работает идеально, но бэкап едет в облачное хранилище в открытом виде, ваш E2E работает только для участка между двумя телефонами. На флангах протекает. К бэкапу и хранилищу нужно относиться с тем же уровнем серьёзности что и к транзиту, иначе вся работа над транзитной криптографией обнуляется.

Сам пост Meta короткий, но whitepaper по ссылке стоит того чтобы потратить вечер. Особенно если вы строите что-то своё в области приватности и безопасной коммуникации.

Я строю уже год с лишним. У себя на Хабре пишу разборы по отдельным кускам ONEMIX (Double Ratchet, кеш сообщений, выбор стека для звонков), и это, в общем, такой же открытый whitepaper в рассрочку, как у Meta, только сильно меньше. На вопросы в комментах отвечу, на критику криптографов реагирую с интересом.

ссылка на оригинал статьи https://habr.com/ru/articles/1038524/