Сквозное шифрование, объясненное по-настоящему
Что говорят провайдеры, когда говорят об E2EE, и о чем они умалчивают. Дидактическое объяснение механизма и его пределов без рекламной упаковки.
Что шифрование означает на самом деле
Зашифровать сообщение — значит превратить его в нечто, напоминающее шум для любого, кто не обладает определенной информацией, называемой ключом. Операция выполняется на устройстве отправителя и с помощью правильного ключа отменяется на устройстве получателя. В промежутке сообщение передается как последовательность байтов без видимого смысла. В этом и заключается простая идея. Остальная часть статьи посвящена нюансам, которые превращают ее, в зависимости от случая, в реальную гарантию или в маркетинговый ярлык.
Прилагательное сквозное — по-английски end-to-end, сокращенно E2EE — добавляет точности. Шифрование выполняется не для того, чтобы промежуточный сервер мог его прочитать и доставить. Оно выполняется для того, чтобы только две стороны — устройство отправителя и устройство получателя — владели ключом. Любой сервер, через который проходит сообщение, видит шум, а не сообщение. В этом заключается техническое отличие от шифрования при транзите, когда контент передается в зашифрованном виде от одного сервера к другому, но каждый сервер, через который он проходит, расшифровывает его для пересылки, временно восстанавливая открытый текст.
Парадокс общего секрета
Существует очевидная проблема. Чтобы два человека могли шифровать и расшифровывать сообщения друг друга, обоим нужен один и тот же ключ. Но как договориться об этом ключе, если все, что они посылают друг другу, по определению проходит через канал, где кто-то может подслушивать? Договориться о ключе в том же канале, где они позже будут его использовать, кажется невозможным: если злоумышленник услышит его при согласовании, он сможет расшифровать все последующее. На протяжении десятилетий классическая криптография решала эту проблему жестким способом: ключи передавались лично, до начала использования, при физических встречах. Послы носили портфели с ключами, вшитыми в подкладку пальто.
В современной электронной почте такое решение не масштабируется. Если бы нам пришлось физически идти домой к каждому человеку, с которым мы намерены общаться в зашифрованном виде, мы бы ни с кем не успели поговорить. Вопрос, поставленный пятьдесят лет назад криптографическим сообществом, звучал так: возможно ли, чтобы два человека, которые не знают друг друга и которые делят только открытый канал, договорились в этом самом открытом канале о секрете, который никто из слушающих канал не сможет узнать?
Элегантность Diffie-Hellman
В 1976 году два математика, Уитфилд Диффи и Мартин Хеллман, доказали нечто, казавшееся невозможным: два человека, разговаривая только через открытый канал — канал, где любой может слышать все, что они говорят, — могут договориться о секретном пароле так, чтобы ни один слушатель не смог его раскрыть. Это звучит как магия. Но это не так: это математика. Обмен ключами Диффи-Хеллмана, как он известен с тех пор, является основой практически всей зашифрованной связи в интернете, и полвека интенсивного использования и всемирного академического анализа подтверждают его надежность. Тот, кто хочет увидеть визуальную интуицию или математику, может читать дальше. Тот, кто предпочитает верить, что это работает, также может продолжить, не теряя нити статьи.
Для тех, кто хочет представить это наглядно, существует известная аналогия с цветами. Представьте, что Алиса и Бруно открыто договариваются о базовом цвете — скажем, желтом — на глазах у Евы, которая их подслушивает. Каждый из них тайно выбирает второй секретный цвет и смешивает свой секрет с желтым. Алиса получает особый оранжевый; Бруно получает особый зеленый. Они обмениваются результатами на глазах у Евы. Теперь каждый смешивает полученный цвет со своим секретом, и оба приходят к одному и тому же конечному цвету, так как порядок смешивания не имеет значения. Ева видела желтый и две промежуточные смеси, но не секреты; без одного из секретов она не сможет получить конечный цвет. Реальная математика заменяет цвета возведением в степень в модулярных группах или на эллиптических кривых, но идея та же: общий секрет создается публично без возможности его восстановления кем-либо в канале.
От Diffie-Hellman до протокола Signal
Сквозное шифрование, которое используют сегодня профессиональные приложения для обмена сообщениями, почти без исключения опирается на элегантную и усиленную версию обмена Диффи-Хеллмана. Протокол Signal, разработанный Тревором Перрином и Мокси Марлинспайком в период с 2013 по 2016 год, является эталоном. Он сочетает в себе две ключевые идеи. Первая — обмен ключами на эллиптических кривых (X25519), который создает первоначальный общий секрет между двумя устройствами. Вторая — так называемый Double Ratchet — двойной храповик, — который автоматически обновляет ключи с каждым сообщением, так что компрометация устройства сегодня не позволяет расшифровать сообщения из прошлого, равно как и сообщения из будущего после поворота храповика.
В Zig обмен X25519, создающий общий секрет между двумя устройствами, умещается в шесть строк с использованием стандартной библиотеки:
const std = @import("std");
const X25519 = std.crypto.dh.X25519;
// Alicia y Bruno generan cada uno un par (privada, pública).
const par_alicia = X25519.KeyPair.generate(io);
const par_bruno = X25519.KeyPair.generate(io);
// Cada parte recibe la clave pública de la otra y deriva el mismo secreto.
const secreto_alicia = X25519.scalarmult(par_alicia.secret_key, par_bruno.public_key) catch unreachable;
const secreto_bruno = X25519.scalarmult(par_bruno.secret_key, par_alicia.public_key) catch unreachable;
// secreto_alicia == secreto_bruno (32 bytes)
А что именно находится внутри std.crypto.dh.X25519? Никакой скрытой магии. Это две короткие функции, которые можно прочитать целиком в самой стандартной библиотеке Zig. Первая выводит публичный ключ из приватного — «gᵃ» обмена:
pub fn recoverPublicKey(secret_key: [secret_length]u8) IdentityElementError![public_length]u8 {
const q = try Curve.basePoint.clampedMul(secret_key);
return q.toBytes();
}
Говоря языком статьи: приватный ключ «умножается» — в эллиптическом смысле, а не в элементарном арифметическом — на базовую точку кривой Curve25519, и результат сериализуется в тридцать два байта. Операция clampedMul — это усиленная версия этого скалярного умножения: она включает в себя меры защиты, которые криптографическое сообщество добавляло годами, чтобы противостоять известным семействам атак. Две строчки тела функции.
Вторая функция комбинирует ваш приватный ключ с публичным ключом, который посылает вам другая сторона. Это «(gᵇ)ᵃ» обмена, то, что создает общий секрет в тридцать два байта, который никто из вас никогда не передавал:
pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) IdentityElementError![shared_length]u8 {
const q = try Curve.fromBytes(public_key).clampedMul(secret_key);
return q.toBytes();
}
Еще две строчки. Полученный публичный ключ интерпретируется как точка на кривой и «умножается» на собственный приватный ключ. Благодаря коммутативности операции над кривой — аналогичной коммутативности умножения степеней, которую мы видели в числовом примере, — обе стороны в конечном итоге получают одну и ту же сериализованную точку: именно тот общий секрет, о котором говорится в статье.
Что защищает сквозное шифрование
Что E2EE защищает хорошо, при условии правильной реализации, — это содержимое сообщения при транзите. Промежуточный сервер, принимающий и пересылающий зашифрованные данные, увидит последовательность непонятных байтов. Злоумышленник с доступом к кабелю, роутеру, точке доступа Wi-Fi увидит то же самое. Провайдер услуг, сохраняющий копии трафика, не сможет прочитать его впоследствии. Правительство, приказавшее оператору связи выдать содержимое, получит те же непонятные байты, которые были у сервера изначально.
Это, в практическом плане, очень много. Это разница между написанием письма внутри непрозрачного конверта и написанием его на открытке. И то, и другое доходит до адресата. Но только одно сохраняет содержимое в тайне от почтальона.
Что не защищает сквозное шифрование
Это стоит знать так же хорошо. E2EE не защищает метаданные: сервер по-прежнему знает, что пользователь А отправляет данные пользователю Б, в какое время, с какой частотой и откуда, хотя и не знает, что именно он говорит. Эти метаданные, как мы уже аргументировали в статье Шифровать — не значит быть приватным, часто более показательны, чем сам контент. Знание того, что кто-то звонил в адвокатскую контору, специализирующуюся на разводах, в пятницу в 22:00 в течение тридцати минут, рассказывает историю, которую содержание звонка никогда бы не рассказало. Это та же ситуация, что и наблюдение за человеком, несколько раз входящим и выходящим из онкологической клиники: не нужно слышать ничего из того, о чем говорят внутри, чтобы представить, что происходит. Один изолированный метаданный может ничего не значить; несколько перекрестных данных рисуют нечто слишком похожее на правду. E2EE не защищает оконечные устройства: если устройство получателя скомпрометировано вредоносной программой, сообщение расшифровывается для этого получателя в обычном режиме, и вредоносная программа его читает. E2EE не защищает от подмены личности собеседника как таковой: если Алиса верит, что разговаривает с Бруно, но злоумышленник вклинился в самом начале (атака man in the middle), а протокол не предусматривает независимой проверки, обе стороны в итоге разговаривают с незваным гостем, думая, что говорят друг с другом.
Есть четвертая вещь, которую стоит сформулировать недвусмысленно. E2EE не мешает провайдеру, утверждающему, что он его предлагает, дополнительно сохранять копию незашифрованного сообщения в своих собственных системах. Утверждение «мои сообщения зашифрованы сквозным шифрованием» и утверждение «провайдер не сохраняет мой контент» — не одно и то же. Приложение может выполнять первое, нарушая второе; мы неоднократно видели это в заголовках газет с 2018 года. Пользователь, если только код клиента не является проверяемым, не имеет технического способа отличить один случай от другого без экспертного расследования. Самый известный случай среди широкой публики: WhatsApp шифрует сообщения сквозным шифрованием при транзите, но если пользователь активирует резервное копирование в iCloud или Google Drive без дополнительного шифрования, эта копия сохраняется в читаемом виде в инфраструктуре третьей стороны, и шифрование нарушается на стороне самого пользователя.
Вопрос, который оператор не хочет слышать
Приложение, утверждающее, что оно шифрует сквозным шифрованием, технически может делать одну из трех вещей в отношении ключей:
- Ключи находятся только на устройствах. Они генерируются и находятся исключительно на устройствах пользователей; оператор их не знает и не хранит. Это оптимальный вариант.
- Оператор может получить доступ, если захочет. Оператор владеет ключами пользователей (или может генерировать их по своему желанию) и хранит их в своих базах данных. Если он захочет или будет вынужден, он сможет прочитать содержимое. Это характерно для большинства «облачных» сервисов.
- Оператор не может получить доступ по дизайну, но он контролирует доступ. У оператора нет ключей, но он контролирует приложение, которое их генерирует. Если его заставят, он может отправить вредоносное обновление, которое перехватит ключи или контент до шифрования. Это характерно для многих коммерческих сервисов E2EE.
Следовательно, оперативный вопрос заключается не в том, зашифровано ли что-то, а в том, кто контролирует устройство и программное обеспечение, управляющее ключами. В Solo2 ключи хранятся исключительно в вашем «Сейфе» (IndexedDB, зашифрованная вашим паролем), а программное обеспечение представляет собой проверяемый открытый исходный код.
Для профессионального читателя
Сквозное шифрование — это инструмент цифрового суверенитета. Но, как и любой инструмент, его эффективность зависит от руки, которая его держит, и почвы, на которой он стоит.
- Где генерируются криптографические ключи и где они физически находятся? Если оператор может получить к ним доступ (даже временно, даже под предлогом восстановления), то E2EE является лишь номинальным.
- Существует ли независимая проверка собеседника (коды безопасности, QR-коды, сравнение вне канала), которая предотвращает атаку man-in-the-middle во время установления разговора?
- Проверяем ли код клиента — открыт ли он, опубликован, воспроизводим — или же он требует доверия слову провайдера о том, что клиент делает на самом деле?
- Какие метаданные генерирует и хранит сервис, и как долго? Даже если контент непрозрачен, метаданные могут восстановить значительную часть конфиденциальной информации.
Эти четыре вопроса не требуют сложной технической информации; они запрашивают информацию, на которую любой честный оператор может ответить в своей публичной документации. Качество и точность ответа говорят о продукте не меньше, чем сам ответ.
Сквозное шифрование, если оно выполнено правильно, является одной из самых изящных конструкций, которые современная криптография принесла в повседневную практику. Оригинальная идея — два человека могут договориться о секрете через открытый канал — принадлежит Whitfield Diffie и Martin Hellman, 1976 год; полвека спустя мы продолжаем жить в ее последствиях. Но, как и в случае с любым техническим обещанием, его ценность зависит от реального исполнения, а не от ярлыка. Вопрос честного профессионала не в том, «зашифровано ли это?», а в том, «у кого ключи?». Ответы имеют разные последствия. Их стоит знать.
Источники и дополнительная литература
- Diffie, W.; Hellman, M. — New Directions in Cryptography, IEEE Transactions on Information Theory, ноябрь 1976 г. Основополагающая статья по криптографии с открытым ключом.
- Perrin, T.; Marlinspike, M. — The Double Ratchet Algorithm, публичная спецификация от Open Whisper Systems, редакция 2016 г. Основа протокола Signal и его промышленных производных.
- RFC 7748 — Elliptic Curves for Security (IETF, январь 2016 г.). Нормативная спецификация кривых X25519 и X448, используемых в современных обменах ключами.
- Ferguson, N.; Schneier, B.; Kohno, T. — Cryptography Engineering: Design Principles and Practical Applications (Wiley, 2010). Главы об обмене ключами и протоколах аутентифицированного шифрования.
- Регламент (ЕС) 2024/1183 о европейской системе цифровой идентификации (eIDAS 2) — устанавливает рамки, в которых независимая проверка собеседника приобретает институциональную поддержку, и где различие между номинальным и реальным шифрованием имеет разные юридические последствия.