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
Правильный источник:
Критическое требование:
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
- различия в поведении браузеров
Ключевой принцип:
криптографические операции должны быть максимально
изолированы от логики приложения
Импорт и экспорт ключей
Методы:
Ошибки:
- экспорт ключей в JWK без защиты
- хранение ключей в localStorage
- передача ключей через URL
Безопасный подход:
- минимизация экспорта
- использование non-extractable keys
При генерации ключей:
Преимущества:
- невозможность утечки ключа через 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
Без версионирования:
- невозможность миграции ключей
- риск несовместимости
- невозможность криптографического обновления
Рандомизация и источник
энтропии
Основной источник:
Ошибка:
- использование внешних RNG
- переиспользование seed
- смешивание криптографического и некриптографического RNG
Ключевой принцип:
энтропия должна поступать только из криптографически стойкого
источника браузера
Итоговые
принципы криптографического дизайна в Web Crypto API
- уникальность nonce является обязательным свойством, а не
рекомендацией
- KDF обязателен при работе с паролями
- domain separation предотвращает перекрёстные атаки протоколов
- AEAD режимы предпочтительнее любых раздельных схем шифрования и
MAC
- ключи должны быть изолированы и по возможности non-extractable
- структура сообщений должна быть формально определена и
версионирована
- криптография должна быть отделена от бизнес-логики приложения