Архитектура протокола Noise
Изучите Noise — платформу для создания специализированных криптографических рукопожатий, используемых в WireGuard, WhatsApp и Lightning.
«Архитектура протокола Noise» — бесплатный урок Cryptology Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Cryptology Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Cryptology Academy содержит 4 уроков всего.
Что такое фреймворк Noise
Фреймворк протокола Noise (Trevor Perrin, 2016 г.; текущая редакция — 2018 г.) предназначен для создания защищённых каналов с помощью небольшого набора примитивов и языка шаблонов. Вместо описания одного протокола Noise определяет словарь шаблонов рукопожатия, описывающих последовательность операций DH и их порядок. Любой допустимый шаблон Noise можно реализовать с конкретными функциями DH (Curve25519 или Curve448), шифрования (AESGCM или ChaChaPoly) и хеширования (SHA-256, SHA-512, BLAKE2). Noise используется в WireGuard, WhatsApp, Signal (как основа X3DH), Lightning Network и I2P.
Роли и ключи Noise
В каждом рукопожатии Noise есть инициатор (I) и ответчик (R). У каждой стороны может быть два типа ключей: статический (долгосрочный ключ идентичности, обозначается как s/S) и эфемерный (создаётся заново для каждого сеанса, обозначается как e/E). Строчные буквы обозначают ключ локальной стороны, а прописные — открытый ключ удалённой стороны. Шаблон Noise определяет, какие ключи отправляются (в открытом или зашифрованном виде) и какие операции DH выполняются. Например, «e» означает «отправить мой эфемерный открытый ключ», а «es» — «выполнить DH(my_ephemeral, remote_static)». Результат каждой операции DH добавляется в текущее состояние хеша рукопожатия.
Симметричное состояние Noise
В основе Noise лежит SymmetricState, который поддерживает три значения: ck (ключ цепочки, инициализированный хешем имени протокола), h (хеш рукопожатия, накапливающийся хеш транскрипта) и k (текущий ключ шифрования). MixKey(input) выполняет HKDF(ck, input), обновляя ck и k. MixHash(data) хеширует data и добавляет результат в h. EncryptAndHash(plaintext) шифрует с помощью k и добавляет шифротекст в h. DecryptAndHash(ciphertext) расшифровывает и добавляет шифротекст в h. Хеш рукопожатия h обеспечивает привязку транскрипта: любое изменение любого сообщения противником изменяет h, из-за чего расшифрование завершается ошибкой. В конце рукопожатия Split() создаёт два отдельных CipherStates для отправки и получения данных.
Шаблон Noise_XX
Noise_XX — наиболее часто используемый шаблон взаимной аутентификации. Он обеспечивает взаимную аутентификацию статическими ключами: статические ключи обеих сторон передаются во время рукопожатия. Шаблон: (1) -> e (инициатор отправляет эфемерный открытый ключ). (2) <- e, ee, s, es (ответчик отправляет эфемерный ключ, выполняет DH(e,e) и DH(e,s_resp), а также отправляет зашифрованный статический ключ). (3) -> s, se (инициатор отправляет зашифрованный статический ключ и выполняет DH(s_init, e_resp)). После шага 3 обе стороны добавили три результата DH в ключ сеанса: ee (прямая секретность), es (аутентификация сервера), se (аутентификация клиента). Ключ сеанса не зависит от компрометации какого-либо долгосрочного ключа после завершения сеанса.
Шаблон Noise_IK (WireGuard)
WireGuard использует шаблон, производный от Noise_IK, в котором инициатор заранее знает статический ключ ответчика. (1) -> e, es, s, ss (инициатор отправляет эфемерный ключ, выполняет DH(e, S_resp), отправляет зашифрованный статический ключ и выполняет DH(s_init, S_resp)). (2) <- e, ee, se (ответчик отправляет эфемерный ключ, выполняет DH(e_resp, e_init) и DH(e_resp, S_init)). Шаблон IK обеспечивает скрытие идентичности инициатора: его статический ключ шифруется статическим ключом ответчика на шаге 1, — и завершение за один RTT. WireGuard добавляет временную метку в зашифрованную полезную нагрузку инициатора, чтобы предотвратить повторное воспроизведение. Благодаря этому Noise-рукопожатие VPN в WireGuard отличается простотой и полностью выполняется за два UDP-пакета.
Хеш рукопожатия Noise и привязка канала
Хеш рукопожатия h в конце рукопожатия Noise — это хеш транскрипта, охватывающий каждое отправленное сообщение. Он служит значением для привязки канала: обе стороны вычисляют один и тот же h, и любой сторонний протокол, которому требуется привязка к сеансу Noise, может включить h в качестве одноразового числа или идентификатора канала. Это позволяет выполнять составную аутентификацию: после рукопожатия Noise можно запустить этап аутентификации сертификатом в стиле TLS, связав сертификат с конкретным сеансом через h. Привязка канала предотвращает атаки с пересылкой учётных данных, при которых данные аутентификации из одного сеанса повторно используются против другого. Split() передаёт приложению h вместе с ключами сеанса.
Отложенные шаблоны Noise и резервный режим
Noise поддерживает отложенные шаблоны для ситуаций, когда инициатор заранее не знает статический ключ ответчика. Noise_NX (у инициатора нет статического ключа; ответчик передаёт свой) аналогичен одностороннему TLS. Noise_XX обрабатывает случай, когда обеим сторонам нужно обменяться ключами. Noise_IK может перейти к Noise_XXfallback, если предположение инициатора о статическом ключе ответчика неверно (например, после смены ключа). Резервный шаблон позволяет ответчику сообщить: «Вы использовали неправильный ключ; вот мой новый открытый ключ», — не раскрывая внешним наблюдателям сам факт перехода к резервному режиму и сохраняя непрозрачность протокола.
Noise в WhatsApp и Signal
WhatsApp и Signal используют Noise_XX для установления защищённых каналов между клиентами и серверами. Двоичный протокол WhatsApp использует Noise_XX с Curve25519, ChaChaPoly и SHA-256. Статический ключ клиента является его долгосрочным ключом идентичности. После рукопожатия Noise на уровне приложения выполняется дополнительная аутентификация (регистрация в Signal, проверка номера телефона). Согласование ключей X3DH (расширенный тройной обмен Диффи — Хеллмана) выполняет четыре операции DH, чтобы установить общий секрет между двумя пользователями посредством асинхронного обмена сообщениями. Это не стандартный шаблон Noise, но он использует похожие концепции добавления результатов DH. Затем для постоянного шифрования сообщений используется Double Ratchet.
Noise и TLS
Noise и TLS 1.3 решают одну и ту же задачу — аутентифицированный обмен ключами, — но придерживаются разных подходов. TLS 1.3 — единый протокол с предписанными наборами шифров, форматами сертификатов (X.509) и расширениями. Он разработан для веб-браузеров и серверов — это универсальный протокол, подходящий большинству случаев. Noise — фреймворк: он не определяет формат сертификатов, PKI или привязку к транспорту. Благодаря этому Noise компактнее (вся реализация Noise в WireGuard занимает менее 400 строк кода) и проще для формального анализа, но приложение должно самостоятельно обрабатывать управление идентичностями. Noise предпочитают для закрытых систем (приложение — сервер, VPN), где PKI избыточна; TLS — для открытых систем (веб-среда), где необходима совместимость сертификатов.
Формальная безопасность Noise
Шаблоны Noise подвергались формальному анализу в модели безопасности eCK (расширенной модели Канетти — Кравчика). Kobeissi, Bhargavan и Blanchet проанализировали Noise с помощью Proverif и получили доказательства аутентификации и конфиденциальности ключей для всех 12 основных шаблонов Noise. Доказательства предполагают стандартное допущение о вычислительной сложности задачи DH (Curve25519), а также безопасность базовых функций AEAD и хеширования. Композиционный характер Noise, в котором каждая операция DH добавляется поэтапно, упрощает анализ по сравнению со сложными протоколами типа TLS, содержащими множество переходов состояний. Криптографическая верификация Noise обеспечила высокую степень уверенности в безопасности протоколов WireGuard и WhatsApp ещё до их развёртывания.
Корректная реализация Noise
Распространённые ошибки при реализации Noise: (1) Путаница шаблонов — использование Noise_IK, когда статический ключ ответчика не был надёжно распространён заранее, приводит к несоответствию идентичности: инициатор может незаметно зашифровать данные неправильным ключом. (2) Защита от повторного воспроизведения — Noise обеспечивает аутентификацию, но не защищает от повторного воспроизведения сообщений транспортной фазы; необходимо контролировать одноразовые числа (64-разрядный счётчик), а переполнение (после 2^64 сообщений) должно запускать смену ключей. (3) Целостность пролога — пролог Noise (строка байтов, добавляемая в h до начала рукопожатия) должен включать весь контекст протокола (версию, выбранные алгоритмы), чтобы предотвращать атаки понижения версии. (4) Неправильное использование PSK — Noise поддерживает расширения PSK для добавления предварительно распределённых ключей; PSK должны обладать высокой энтропией, а не быть паролями пользователей.
Викторина по фреймворку Noise
Что означает обозначение «es» в шаблоне рукопожатия Noise?
Итоги фреймворка Noise
Noise — это фреймворк для создания протоколов аутентифицированного обмена ключами с использованием языка шаблонов операций DH. SymmetricState поддерживает ключ цепочки (ck), хеш транскрипта (h) и ключ шифрования (k), которые обновляются с помощью MixKey/MixHash. Noise_XX обеспечивает взаимную аутентификацию за 1,5 RTT; Noise_IK (WireGuard) завершается за 1 RTT при заранее известном ключе ответчика. Хеш рукопожатия h служит для привязки канала. Все основные шаблоны Noise прошли формальную верификацию с помощью Proverif. Noise предпочтительнее TLS для протоколов закрытых систем (WireGuard, WhatsApp), где PKI не требуется. Корректная реализация требует защиты от повторного воспроизведения, целостности пролога и PSK с высокой энтропией.
Часто задаваемые вопросы
Урок «Архитектура протокола Noise» бесплатный?
Да — полный текст урока «Архитектура протокола Noise» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Cryptology Academy, подпишись на CoddyKit PRO. Курс Cryptology Academy содержит 4 уроков всего.
Чему я научусь в уроке «Архитектура протокола Noise»?
Изучите Noise — платформу для создания специализированных криптографических рукопожатий, используемых в WireGuard, WhatsApp и Lightning. Ты практикуешь Cryptology Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Cryptology Academy?
Предыдущий опыт не требуется. Cryptology Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Архитектура протокола Noise»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Cryptology Academy?
Да. Каждый урок Cryptology Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Протокол Needham—Schroeder и атаки
- Протокол Station-to-Station (STS)
- Архитектура протокола Noise
- Принципы проектирования защищенных протоколов