Проверка целостности и аутентификация через Poly1305

Проверка целостности в криптографических протоколах на базе TweetNaCl.js строится вокруг аутентифицированных конструкций, где шифрование и контроль целостности объединены в одну операцию. Основной механизм, обеспечивающий защиту от подмены данных, — MAC на основе Poly1305, используемый совместно с поточным шифром XSalsa20.

Poly1305 — это быстрый одноразовый код аутентификации сообщений (MAC), который вычисляет 128-битный тег для произвольного сообщения и секретного ключа. Его ключевая особенность заключается в том, что он предназначен для работы только с уникальным ключом на каждое сообщение.

В TweetNaCl.js Poly1305 не используется как самостоятельный примитив в большинстве сценариев. Он встроен в конструкцию:

  • XSalsa20 (шифрование)
  • Poly1305 (аутентификация)

Эта связка образует схему secretbox, обеспечивающую одновременно конфиденциальность и целостность.


Как устроен secretbox в TweetNaCl.js

Функция nacl.secretbox(message, nonce, key) реализует аутентифицированное шифрование. Внутри происходит несколько этапов:

  1. Из ключа и nonce (одноразового значения) генерируется потоковый ключ
  2. Сообщение шифруется с помощью XSalsa20
  3. На результат вычисляется Poly1305 MAC
  4. MAC добавляется к шифротексту

Итоговая структура:

ciphertext = XSalsa20(message, nonce, key)
tag        = Poly1305(ciphertext, one_time_key)
output     = tag || ciphertext

Ключевой момент: Poly1305 применяется не к исходному сообщению, а к уже зашифрованным данным.


Проверка целостности при расшифровании

При вызове:

nacl.secretbox.open(box, nonce, key)

происходит обратный процесс:

  1. Из ключа и nonce повторно вычисляется потоковый ключ
  2. Извлекается Poly1305 тег из входных данных
  3. Пересчитывается MAC для полученного ciphertext
  4. Выполняется сравнение тегов в константное время

Если теги не совпадают — данные считаются повреждёнными или поддельными, и функция возвращает null.


Критическая роль nonce

Nonce (number used once) — обязательный параметр, который напрямую влияет на безопасность Poly1305 в данной конструкции.

Важно:

  • повтор nonce с тем же ключом полностью ломает безопасность
  • Poly1305 предполагает одноразовость ключа, который в TweetNaCl.js выводится из nonce + секретного ключа

Даже если сообщение разное, повтор nonce позволяет атакующему восстановить информацию о ключе аутентификации.


Poly1305 как MAC: математическая основа

Poly1305 работает в поле по модулю (2^{130} - 5) и вычисляет полиномиальную функцию от блоков сообщения:

(m, r, s) = (_{i=1}^{n} m_i r^i (2^{130}-5)) + s

где:

  • (m_i) — блоки сообщения
    1. — часть ключа (ограниченная по битам)
    1. — сдвиговая часть ключа (16 байт)

В практической реализации TweetNaCl.js все эти операции скрыты внутри оптимизированного C-подобного кода, компилированного в JavaScript.


Почему Poly1305 безопасен в этой схеме

Безопасность обеспечивается комбинацией факторов:

  • ключ Poly1305 уникален для каждого сообщения (через nonce)
  • вычисление MAC происходит по шифротексту, а не по открытому тексту
  • сравнение тегов выполняется в константное время
  • XSalsa20 исключает утечки структуры данных до проверки целостности

Таким образом, атакующий не может:

  • подделать корректный MAC без знания ключа
  • модифицировать шифротекст без обнаружения
  • извлечь информацию о ключе через наблюдение за тегами

Связь Poly1305 и nacl.box / nacl.secretbox

В TweetNaCl.js существует две основные схемы, использующие Poly1305:

secretbox

  • симметричное шифрование
  • один ключ 32 байта
  • Poly1305 применяется к XSalsa20(ciphertext)

box

  • асимметричное шифрование (Curve25519)
  • общий секрет вычисляется через ECDH
  • далее используется тот же secretbox (XSalsa20 + Poly1305)

Фактически:

nacl.box = nacl.secretbox + ECDH key exchange

Poly1305 остаётся неизменным элементом на уровне аутентификации.


Важные особенности реализации в TweetNaCl.js

1. Отсутствие “сырого” Poly1305 API

Библиотека не предоставляет прямую функцию типа:

nacl.poly1305()

Вместо этого Poly1305 встроен внутрь secretbox.

2. Константное сравнение тегов

Проверка MAC реализована так, чтобы избежать timing attacks:

  • сравнение не прерывается при первом несовпадении
  • время выполнения не зависит от позиции ошибки

3. Размер тега

Poly1305 генерирует 16-байтный (128-bit) аутентификационный тег:

tag.length === 16

Типичная структура данных secretbox

[ 16 bytes Poly1305 tag | encrypted message (XSalsa20) ]

Nonce при этом передаётся отдельно и не включается в пакет.


Пример использования в JavaScript

const nacl = require('tweetnacl');
nacl.util = require('tweetnacl-util');

const key = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);

const message = nacl.util.decodeUTF8("секретное сообщение");

const box = nacl.secretbox(message, nonce, key);

const opened = nacl.secretbox.open(box, nonce, key);

if (opened === null) {
  throw new Error("Повреждённые или поддельные данные");
}

const decoded = nacl.util.encodeUTF8(opened);

Типовые ошибки при работе с Poly1305-основанной схемой

Повтор nonce

Самая критичная ошибка:

  • один и тот же nonce + ключ → повторный Poly1305 key
  • это позволяет атакующему сравнивать MAC и строить утечки

Изменение ciphertext без проверки MAC

Если игнорировать результат secretbox.open, можно обработать поддельные данные.

Неправильное хранение ключей

Poly1305 полностью зависит от секретного ключа, утечка которого компрометирует всю схему.


Внутренний смысл Poly1305 в архитектуре TweetNaCl

Poly1305 здесь выполняет строго одну роль — защиту целостности уже зашифрованного текста. Он не участвует в шифровании и не влияет на конфиденциальность напрямую.

Его значение в системе:

  • обнаружение любых изменений ciphertext
  • защита от активных атак (tampering)
  • гарантия, что расшифровка выполняется только для подлинных данных

Без Poly1305 потоковое шифрование XSalsa20 было бы уязвимо к битовым модификациям.


Практическое понимание модели безопасности

Комбинация XSalsa20 + Poly1305 в TweetNaCl.js реализует модель:

  • confidentiality (шифрование)
  • integrity (целостность)
  • authenticity (аутентичность)

Именно Poly1305 отвечает за последние два свойства, выступая криптографическим фильтром перед этапом расшифрования.