Хранение криптографических материалов в веб-приложениях на базе
JavaScript с использованием Stanford JavaScript Crypto Library (SJCL)
связано с набором специфических угроз, обусловленных как особенностями
браузерной среды, так и моделью работы самой библиотеки.
К криптографическим материалам в контексте SJCL относятся:
- симметричные ключи шифрования (AES-ключи)
- ключи для HMAC и аутентификации
- соль (salt) для KDF (PBKDF2, Scrypt-подобные схемы)
- векторы инициализации (IV)
- случайные значения, генерируемые через PRNG SJCL
- производные ключи, полученные из паролей
Каждый из этих элементов имеет различную степень чувствительности, но
компрометация любого из них может привести к деградации всей
криптографической схемы.
Угрозы со стороны
JavaScript-среды
Выполнение кода в одном
пространстве
JavaScript в браузере работает в общей среде выполнения, где любой
загруженный скрипт имеет потенциальный доступ к памяти приложения. Это
создаёт базовую угрозу:
- внедрение вредоносного скрипта через XSS
- подмена библиотек (supply chain attack через CDN)
- динамическая модификация функций SJCL в рантайме
SJCL может быть полностью корректной библиотекой, но её использование
в заражённом контексте делает криптографические операции
бессмысленными.
XSS как основной канал
компрометации
Наиболее критическая угроза при хранении ключей в браузере — XSS
(Cross-Site Scripting). При наличии XSS атакующий получает
возможность:
- извлечь ключи из переменных JavaScript
- перехватить результаты sjcl.encrypt / sjcl.decrypt
- подменить функции генерации случайных чисел
- логировать вводимые пароли до их обработки KDF
Особенность SJCL заключается в том, что криптография происходит в
памяти JavaScript, а значит любой доступ к DOM-скриптам эквивалентен
доступу к ключам.
Угрозы хранения в
браузерных хранилищах
localStorage и
sessionStorage
Хранение криптографических материалов в localStorage:
- не защищено от XSS
- доступно любому скрипту в origin
- сохраняется между сессиями
sessionStorage ограничивает срок жизни данных, но не снижает угрозу
XSS.
Типичная ошибка — хранение:
- AES ключей в открытом виде
- зашифрованных ключей без дополнительной защиты
- seed для PRNG
IndexedDB
IndexedDB часто используется для хранения больших зашифрованных
объектов, однако:
- не обеспечивает криптографической изоляции
- уязвим к доступу через вредоносный JS-код
- может быть экспортирован через API браузера
Угрозы генерации случайных
чисел
SJCL использует собственный PRNG (основанный на ARC4/RC4-подобных
конструкциях и энтропийном пуле браузера). Основные риски:
- недостаток энтропии при старте
- предсказуемость состояния PRNG при раннем использовании
- отсутствие должной инициализации в headless-окружениях
- деградация качества случайности при повторном использовании
seed
Слабая случайность напрямую влияет на:
- повтор IV в AES-CBC/CTR
- предсказуемость ключей
- уязвимость к known-plaintext атакам
Повторное использование IV и
nonce
При неправильной работе с SJCL часто нарушается требование
уникальности IV:
- повтор IV в CBC приводит к раскрытию структуры сообщений
- повтор nonce в CTR фактически разрушает конфиденциальность
- использование фиксированного IV в тестах переносится в
production
SJCL не навязывает безопасную стратегию использования IV, оставляя
это на уровне разработчика.
Угрозы памяти JavaScript
Доступность данных в heap
Все криптографические материалы в SJCL находятся в памяти
Jav * aScript:
- ключи после использования остаются в heap до сборки мусора
- garbage collector не гарантирует немедленного удаления
- возможны дампы памяти через devtools или эксплойты браузера
Side-channel через время
выполнения
Даже в браузере возможны:
- timing attacks на операции сравнения
- утечки через различия времени расшифрования
- наблюдение за нагрузкой CPU при криптографических операциях
Угрозы со стороны
расширений браузера
Браузерные расширения часто обладают расширенными правами:
- доступ к DOM всех страниц
- перехват network requests
- чтение и модификация JavaScript runtime
Это делает возможным:
- извлечение ключей SJCL из памяти страницы
- подмену результатов шифрования
- внедрение вредоносного кода до загрузки приложения
Проблемы хранения паролей и
KDF
SJCL предоставляет PBKDF2 для преобразования пароля в ключ.
Угрозы:
- слишком малое число итераций
- повторное использование соли
- хранение соли рядом с зашифрованными данными без защиты
- кэширование производных ключей в памяти
При слабой конфигурации KDF атака перебора становится вычислительно
тривиальной.
Угрозы сериализации и
десериализации
SJCL часто используется через JSON-представления шифротекста:
- sjcl.encrypt возвращает JSON-структуру
- sjcl.decrypt принимает строку JSON
Риски:
- подмена параметров (IV, salt, iter)
- внедрение некорректных структур
- атаки через deserialization logic abuse
- изменение параметров KDF для ослабления защиты
Утечки через логирование и
отладку
Разработческие практики часто приводят к утечкам:
- логирование зашифрованных объектов вместе с ключевыми
параметрами
- вывод plaintext в console.log
- хранение промежуточных значений KDF в debug режиме
- использование production ключей в development окружении
Угрозы цепочки поставки
SJCL часто подключается через:
- CDN
- npm зависимости
- копирование исходного кода в проект
Риски:
- подмена версии библиотеки на модифицированную
- внедрение бэкдоров в fork SJCL
- отсутствие контроля целостности (SRI не используется)
- компрометация npm-пакетов
Угрозы долговременного
хранения ключей
При хранении криптографических материалов в браузере:
- отсутствует аппаратная изоляция
- нет secure enclave (в отличие от WebCrypto + hardware-backed
keys)
- ключи доступны любому процессу в origin
- невозможно гарантировать удаление после использования
Долговременное хранение увеличивает вероятность компрометации через
накопленные атаки.
Комбинированные сценарии
атак
На практике угрозы редко существуют изолированно. Типовые
цепочки:
- XSS → извлечение localStorage → дешифрование данных через SJCL
API
- подмена CDN → внедрение backdoored SJCL → утечка всех ключей
- расширение браузера → перехват heap → восстановление ключей AES
- слабый KDF → оффлайн brute-force на украденных данных
SJCL в таких сценариях становится точкой исполнения, а не защиты.