Защита от атак через выбор параметров и правильный дизайн

Web Crypto API предоставляет криптографические примитивы уровня браузера через crypto.subtle, но сама по себе не гарантирует корректную криптографическую безопасность системы. Основные атаки возникают не на уровне алгоритмов, а на уровне их неправильной композиции, выбора параметров и структуры протокола.

Ключевой принцип: криптографическая стойкость системы определяется не API, а дизайном протокола и параметризацией алгоритмов

Типовые классы атак:

  • повторное использование nonce/IV
  • предсказуемые ключи или соли
  • слабые параметры KDF
  • отсутствие аутентификации данных
  • некорректный выбор режима шифрования
  • утечка информации через формат сообщений
  • атаки на повтор (replay attacks)
  • отсутствие разделения контекста (domain separation)

Криптографические примитивы и границы их безопасности

Symmetric encryption: AES-GCM

Наиболее распространённый выбор в Web Crypto API:

  • AES-GCM — обеспечивает конфиденциальность и целостность
  • AES-CBC — устаревший режим без встроенной аутентификации

Критический факт:

AES-GCM полностью ломается при повторном использовании nonce (IV)

IV_{i} IV_{j} i j

Повтор IV приводит к:

  • восстановлению XOR между plaintexts
  • компрометации ключа при известных сообщениях
  • подделке сообщений

Следствие:

  • IV должен быть уникальным, не обязательно случайным
  • допустимы счётчики, 96-битные nonce, UUID-подобные схемы

Ошибки генерации IV

Частая ошибка — использование:

  • Math.random()
  • timestamp
  • коротких случайных значений
  • повторно используемых seed

Правильный источник:

  • crypto.getRandomValues()

Критическое требование:

IV не должен зависеть от состояния приложения


Генерация ключей и CSPRNG

Web Crypto API предоставляет:

  • crypto.subtle.generateKey
  • crypto.getRandomValues

Важно:

  • генерация ключей должна происходить внутри API
  • недопустимо вручную конструировать ключи из строк

Ошибка дизайна:

  • использование паролей напрямую как ключей
  • отсутствие KDF

Производные ключи и KDF

PBKDF2

Используется через Web Crypto API:

  • поддерживается нативно
  • требует большого числа итераций

Основные параметры:

  • salt
  • iterations
  • hash function

Критическая ошибка:

повторное использование salt приводит к атаке радужных таблиц

K_{derived} = (password, salt, iterations)

Риски:

  • низкое число итераций ускоряет brute-force
  • отсутствие уникального salt делает пароли уязвимыми

HKDF

Используется для:

  • расширения ключей
  • разделения контекстов

Параметры:

  • salt (может быть пустым, но нежелательно)
  • info (ключевой элемент domain separation)

Ключевой принцип:

один и тот же master key должен порождать разные ключи для разных целей через info


Domain separation и контекстная изоляция

Одна из самых недооценённых проблем:

  • один ключ используется в разных протоколах
  • отсутствие различения сообщений по назначению

Решение:

  • включение контекста в info
  • явная версия протокола
  • тип сообщения

Пример структуры:

  • "auth:v1:session"
  • "enc:v1:file"
  • "sign:v1:metadata"

Асимметричная криптография: RSA-OAEP и ECDH

RSA-OAEP

Используется для шифрования ключей.

Ошибка:

  • использование RSA-PKCS1 v1.5 (устаревший режим)
  • отсутствие OAEP padding

Риски:

  • padding oracle attacks
  • предсказуемость структуры

ECDH

Используется для обмена ключами.

Критически важно:

  • проверка публичных ключей
  • фиксированные параметры кривой
  • защита от invalid curve attacks

Ошибки:

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

Аутентифицированное шифрование

На практике безопасные системы используют:

  • AES-GCM
  • ChaCha20-Poly1305 (не в Web Crypto API напрямую)

Ключевой принцип:

шифрование без аутентификации считается криптографически неполным

Ошибки:

  • AES-CBC без HMAC
  • ручная реализация MAC без строгого разделения ключей

Уникальность nonce и её нарушение

Для GCM:

P()

Практические последствия:

  • при больших объёмах данных вероятность коллизий растёт
  • повтор nonce = критическая уязвимость

Стратегии:

  • счётчик + случайный префикс
  • централизованный генератор IV
  • хранение состояния

Формат сообщений и утечки через структуру

Даже при сильном шифровании возможны утечки через:

  • длину сообщений
  • повторяемость структур
  • порядок полей
  • наличие фиксированных заголовков

Ошибки:

  • отсутствие padding
  • предсказуемые JSON структуры
  • повторяемые метаданные

Решения:

  • добавление padding до фиксированной длины
  • сериализация с рандомизацией порядка полей (ограниченно)
  • включение версии и случайного nonce в payload

Replay attacks и защита

Web Crypto API не предоставляет защиты от повторов.

Типичная ошибка:

  • использование одного и того же токена без срока жизни
  • отсутствие уникального nonce на уровне протокола

Защита:

  • включение timestamp
  • использование одноразовых nonce
  • хранение использованных идентификаторов

Ошибки работы с JWK

JSON Web Key (JWK) часто используется для импорта ключей:

Риски:

  • подмена параметров ключа
  • отсутствие валидации поля alg
  • доверие внешним JWK без проверки источника

Ошибка дизайна:

  • импорт ключа из ненадёжного JSON без криптографической привязки

Side-channel и особенности браузерной среды

Хотя Web Crypto API реализован нативно:

риски остаются:

  • timing differences при обработке JS-логики
  • утечки через exception handling
  • различия в поведении браузеров

Ключевой принцип:

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


Импорт и экспорт ключей

Методы:

  • importKey
  • exportKey

Ошибки:

  • экспорт ключей в JWK без защиты
  • хранение ключей в localStorage
  • передача ключей через URL

Безопасный подход:

  • минимизация экспорта
  • использование non-extractable keys

Non-extractable keys

При генерации ключей:

  • extractable: false

Преимущества:

  • невозможность утечки ключа через API
  • защита от компрометации памяти JS

Ограничение:

  • невозможность резервного копирования ключа

Конструкция безопасного шифрования

Типичная устойчивая схема:

  • AES-GCM для данных
  • HKDF для производных ключей
  • уникальный IV на сообщение
  • domain separation через info

Структура сообщения:

  • version
  • key_id
  • nonce
  • ciphertext
  • auth_tag (встроен в GCM)

Частые архитектурные ошибки

  • использование одного ключа для шифрования и подписи
  • отсутствие разделения client/server контекстов
  • повторное использование IV ради «оптимизации»
  • ручная реализация криптографических алгоритмов поверх Web Crypto
  • смешивание разных алгоритмов без версии протокола

Версионирование криптографических схем

Любая система должна учитывать эволюцию алгоритмов:

  • v1 — AES-GCM-128
  • v2 — AES-GCM-256 + HKDF
  • v3 — смена KDF или hash function

Без версионирования:

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

Рандомизация и источник энтропии

Основной источник:

  • crypto.getRandomValues()

Ошибка:

  • использование внешних RNG
  • переиспользование seed
  • смешивание криптографического и некриптографического RNG

Ключевой принцип:

энтропия должна поступать только из криптографически стойкого источника браузера


Итоговые принципы криптографического дизайна в Web Crypto API

  • уникальность nonce является обязательным свойством, а не рекомендацией
  • KDF обязателен при работе с паролями
  • domain separation предотвращает перекрёстные атаки протоколов
  • AEAD режимы предпочтительнее любых раздельных схем шифрования и MAC
  • ключи должны быть изолированы и по возможности non-extractable
  • структура сообщений должна быть формально определена и версионирована
  • криптография должна быть отделена от бизнес-логики приложения