Инициализационный вектор (IV, Initialization Vector) и одноразовый вектор (nonce) используются для того, чтобы одинаковые открытые сообщения при одинаковом ключе давали различный шифртекст. В современных режимах работы блочных шифров IV перестал быть просто «дополнительными данными» и превратился в критически важный элемент криптографической стойкости.
Основное требование к IV в большинстве режимов — уникальность. В некоторых режимах достаточно уникальности, в других требуется криптографическая случайность. Нарушение этих требований приводит к утечке структуры данных, восстановлению исходного текста и иногда к полному компрометированию ключа.
В библиотеке SJCL (Stanford Javascript Crypto Library) это особенно важно, поскольку типичные сценарии использования включают CTR, CBC и аутентифицированные режимы, такие как CCM и OCB2, где повтор IV приводит к детерминированным и предсказуемым последствиям.
Режим CTR (Counter Mode) превращает блочный шифр в потоковый. Генерация шифртекста происходит по схеме:
y = P E_K(IV + i)
где:
Критическая уязвимость возникает при повторном использовании IV с тем же ключом. Если два сообщения зашифрованы с одинаковым IV:
C_1 = P_1 S, C_2 = P_2 S
где поток (S) идентичен.
При XOR двух шифртекстов поток исключается:
C_1 C_2 = P_1 P_2
Это полностью раскрывает линейную связь между двумя открытыми сообщениями. При известной структуре одного из сообщений восстановление второго становится тривиальным.
В SJCL использование CTR требует строгого контроля генерации IV. Ошибки типичны в случаях:
CBC (Cipher Block Chaining) использует IV для первого блока:
C_1 = E_K(P_1 IV)
Если два сообщения зашифрованы с одинаковым IV, то первый блок становится уязвимым к анализу:
C_1^{(a)} C_1^{(b)} = E_K(P_1^{(a)} IV) E_K(P_1^{(b)} IV)
Хотя CBC менее подвержен прямому раскрытию XOR-структуры, повтор IV приводит к утечке:
Особенно опасно это в веб-приложениях, где SJCL используется для шифрования структурированных данных (JSON, токены, cookies).
Режим CCM (Counter with CBC-MAC) совмещает аутентификацию и шифрование. Он использует nonce, который должен быть уникальным для каждого сообщения.
При повторе nonce происходит сразу два негативных эффекта:
Формально:
S = E_K(Nonce counter)
и при повторе nonce:
S_1 = S_2
Это приводит к:
В SJCL CCM считается безопасным только при строгой генерации nonce, обычно через криптографически стойкий генератор или счётчик с гарантией отсутствия повторов.
OCB2 (Offset Codebook Mode 2), реализованный в SJCL, объединяет шифрование и аутентификацию в один проход. Его безопасность критически зависит от уникальности nonce.
При повторном nonce:
OCB2 исторически имеет дополнительную сложность: при неправильной реализации повтор nonce может приводить к более сильным атакам, чем в CTR или CBC, из-за тесной связи между шифрованием и аутентификацией.
На практике проблемы возникают не в алгоритмах, а в способах их применения.
var iv = [0, 0, 0, 0];
Такое использование полностью уничтожает семантическую стойкость CTR и CBC.
var iv = [];
for (var i = 0; i < 4; i++) iv.push(Math.random() * 0xffffffff);
Math.random() не является криптографически стойким источником. Повторяемость последовательностей в разных окружениях приводит к предсказуемым IV.
В SPA-приложениях часто сохраняется состояние шифрования, включая nonce. При восстановлении состояния разработчики повторно используют старый IV.
var iv = [Date.now()];
Временная метка обладает низкой энтропией и предсказуема. При массовых запросах приводит к коллизиям.
Повтор IV в SJCL приводит к различным уровням компрометации в зависимости от режима:
Во всех случаях ключ остаётся неизменным, но его безопасность становится формальной: при достаточном объёме перехваченных данных восстановление сообщений становится практической задачей.
Криптографически корректное использование требует:
sjcl.random.randomWordsПример корректного подхода:
var iv = sjcl.random.randomWords(4);
var cipher = sjcl.encrypt(key, data, { iv: iv });
Ключевой принцип — отсутствие любой детерминированности в генерации IV, даже косвенной.
При использовании SJCL в протоколах уровня приложения (JWT-подобные токены, защищённые cookies, обмен сообщениями) повтор IV приводит к системным последствиям:
В потоковых режимах это превращается в устойчивую утечку информации даже при отсутствии прямого дешифрования.
Повтор IV фактически означает повтор использования одного и того же keystream’а:
S = E_K(IV)
и при повторе:
S_1 = S_2 C_1 C_2 = P_1 P_2
Это эквивалентно классической атаке на одноразовый блокнот при повторном использовании ключа.