Сторонние (side-channel) атаки в JavaScript-криптографии возникают не из-за взлома алгоритмов напрямую, а из-за утечек информации через косвенные каналы: время выполнения операций, особенности использования памяти, поведение кэша, различия в обработке ошибок и даже особенности работы интерпретатора.
В контексте Jsrsasign это особенно важно, поскольку библиотека реализует криптографические примитивы на чистом JavaScript, а значит работает в среде, которая изначально плохо изолирована от наблюдаемых временных и поведенческих утечек.
Классическая криптография предполагает идеализированную модель вычислений, где операции выполняются детерминированно и не раскрывают дополнительной информации. Реальные JavaScript-движки нарушают эту модель.
Основные каналы утечки:
Временные атаки (timing attacks) Разница во времени выполнения операций может зависеть от секретных данных. Например, ветвление алгоритма RSA в зависимости от значения бита ключа или различная длина обработки больших чисел.
Атаки через кэш и память Хотя в браузере доступ к низкоуровневому кэшу ограничен, косвенные эффекты (например, работа с большими объектами, аллокации BigInt-подобных структур) могут создавать наблюдаемые различия.
Поведенческие различия алгоритмов Некоторые операции криптографии могут вести себя по-разному при обработке нулевых байтов, ведущих нулей или нестандартных входных данных.
JIT-оптимизация JavaScript Оптимизирующие компиляторы могут «раскрывать» различия в коде, которые изначально казались нейтральными.
Библиотека Jsrsasign реализует криптографические операции (RSA, ECDSA, HMAC, X.509) на JavaScript и используется в средах без нативного WebCrypto или для расширенной функциональности.
Ключевая проблема: JavaScript-реализация не может гарантировать строгую константную временную модель выполнения.
Особенно чувствительные зоны:
RSA в Jsrsasign опирается на большие целые числа и модульную экспоненту. В идеальной реализации используется blinding и constant-time exponentiation.
В JavaScript это усложняется:
Упрощённая модель RSA-операции:
result = message ^ d mod n
Если реализация экспоненты выполняется через поразрядное возведение в
степень, то время работы может зависеть от количества единичных битов в
ключе d.
Даже микроскопические различия (наносекунды) в серверной среде или при многократных запросах могут быть статистически агрегированы.
ECDSA чувствителен к утечкам особенно сильно.
Критическая точка — значение k (nonce):
Jsrsasign может использовать встроенные генераторы случайных чисел браузера, но проблема возникает при:
Даже простые операции могут быть источником утечки:
== вместо constant-time
compare)Обычное сравнение строк:
if (signature === expectedSignature)
выполняется с ранним выходом при первом несовпадении символа, что создаёт временной канал утечки.
В отличие от WebCrypto API, Jsrsasign:
Это означает, что даже одинаковый код может иметь различимую временную сигнатуру в разных окружениях.
Если сервер использует Jsrsasign для проверки JWT или JWS:
При проверке API-ключей:
Jsrsasign активно работает с X.509 и ASN.1 структурами. Разные пути обработки ошибок могут:
JavaScript накладывает фундаментальные ограничения:
Даже попытки реализовать constant-time в чистом JS остаются статистически уязвимыми.
WebCrypto выполняет операции в нативной реализации ОС:
const key = await crypto.subtle.generateKey(
{ name: "RSA-PSS", modulusLength: 2048, hash: "SHA-256" },
true,
["sign", "verify"]
);
Это снижает вероятность side-channel утечек за счёт:
Jsrsasign допустимо использовать для:
Недопустимо:
Для предотвращения timing leaks:
function constantTimeEqual(a, b) {
if (a.length !== b.length) return false;
let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
}
return result === 0;
}
Такой подход убирает ранний выход из цикла.
Для ECDSA и RSA padding критично:
crypto.getRandomValuesSide-channel атаки в веб-среде часто имеют форму:
Даже если Jsrsasign используется корректно, комбинация с UI-логикой может создавать утечки.
В браузере криптография редко изолирована. Часто она связана с:
Любая задержка:
может стать измеряемым сигналом.
Разные движки ведут себя по-разному:
Это создаёт дополнительный уровень неопределённости, который затрудняет анализ безопасности Jsrsasign в реальных условиях.
Даже при идеальной реализации Jsrsasign:
Поэтому side-channel безопасность в JavaScript определяется не только кодом библиотеки, но и всей экосистемой исполнения.