Атака man-in-the-middle (MITM) возникает в момент, когда канал связи между двумя сторонами оказывается под контролем третьей стороны, способной читать, изменять или подменять передаваемые данные. В веб-приложениях, использующих криптографию на стороне клиента, включая решения на базе Stanford JavaScript Crypto Library (SJCL), такая угроза особенно критична из-за высокой зависимости от корректной передачи ключевого материала и исходного кода приложения.
В JavaScript-среде MITM может проявляться не только на уровне сетевого трафика, но и на уровне доставки самого кода (например, через подмену скриптов при отсутствии HTTPS или компрометацию CDN).
Основные точки атаки MITM в приложениях с SJCL:
Особенность браузерной среды заключается в том, что криптографический код и данные выполняются в одном доверенном контексте. Если этот контекст скомпрометирован, криптография теряет смысл.
Stanford JavaScript Crypto Library предоставляет набор примитивов для симметричного шифрования, HMAC, хэширования и работы с эллиптическими кривыми.
Ключевые модули:
sjcl.encrypt / sjcl.decrypt — симметричное
шифрованиеsjcl.ecc — эллиптическая криптографияsjcl.hash — хэш-функцииsjcl.misc.hmac — коды аутентификации сообщенийsjcl.random — генерация случайных чиселОднако важно понимать: библиотека не решает проблему MITM на уровне протокола. Она предоставляет инструменты, но не гарантирует безопасный канал передачи ключей.
Рассмотрим типичный сценарий обмена ключами без аутентификации:
Если атакующий находится между ними, он может:
В SJCL это особенно опасно при использовании
sjcl.ecc.elGamal или ECDH-обменов без проверки подлинности
ключей.
// Упрощённый пример ECDH без аутентификации
const client = sjcl.ecc.elGamal.generateKeys(256);
const serverPublic = getServerPublicKey(); // может быть подменён
const sharedSecret = client.sec.dh(serverPublic);
Если serverPublic получен через незащищённый канал
(HTTP, уязвимый WebSocket), MITM может заменить его на свой ключ.
На практике базовой защитой выступает HTTPS (TLS). SJCL не заменяет транспортный уровень.
Ключевой момент:
Без TLS любые криптографические операции в браузере становятся уязвимыми к MITM.
Для защиты ECDH необходимо подтверждение подлинности ключей.
Используются подходы:
Пример проверки отпечатка:
const pubKey = serverPublic.serialize();
const hash = sjcl.hash.sha256.hash(pubKey);
const fingerprint = sjcl.codec.hex.fromBits(hash);
if (fingerprint !== trustedFingerprint) {
throw new Error("Key mismatch - possible MITM");
}
SJCL поддерживает подписи через ECDSA:
const keys = sjcl.ecc.ecdsa.generateKeys(256);
const signature = keys.sec.sign(sjcl.hash.sha256.hash(message));
const valid = keys.pub.verify(sjcl.hash.sha256.hash(message), signature);
В контексте защиты от MITM ключи серверов подписываются доверенным центром или заранее известным ключом.
MITM часто не только перехватывает, но и модифицирует сообщения. Для защиты используется HMAC:
const key = sjcl.codec.utf8String.toBits("shared-secret");
const hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
const tag = hmac.encrypt(message);
При изменении сообщения проверка HMAC провалится, что выявляет вмешательство.
Отдельный вектор MITM — подмена самой библиотеки SJCL или пользовательского кода.
Риски:
Основная защита:
Пример SRI:
<script src="sjcl.js"
integrity="sha384-..."
crossorigin="anonymous"></script>
На практике уязвимости возникают не из-за SJCL, а из-за неправильного использования:
localStorage без защитыНадёжная схема с использованием SJCL обычно включает:
Такая комбинация устраняет ключевую проблему MITM: невозможность незаметной подмены ключевого обмена.
Даже при корректной криптографии возможны дополнительные сценарии:
SJCL не может защитить от атак, происходящих внутри доверенного исполнения JavaScript-контекста. В этом случае нарушается сама модель доверия.
Типовой безопасный поток:
Stanford JavaScript Crypto Library предоставляет криптографические примитивы, но не реализует защищённый протокол передачи ключей. Защита от MITM достигается только при построении полного протокола, включающего:
Без этих уровней даже корректно используемые функции шифрования становятся формальной защитой без реальной устойчивости к атакующему посреднику.