Шифрование само по себе не гарантирует, что сообщение было отправлено именно ожидаемым источником или что оно не было изменено в процессе передачи. Для решения этих задач применяются механизмы аутентификации и проверки целостности. В библиотеке SJCL эти аспекты реализуются через комбинацию криптографических примитивов: HMAC, режимы аутентифицированного шифрования и проверка тегов подлинности.
При передаче зашифрованных данных возможны следующие атаки:
Шифрование (например, AES) скрывает содержимое, но не предотвращает такие атаки. Поэтому используется дополнительный слой — криптографическая аутентификация.
SJCL предоставляет реализацию HMAC (Hash-based Message Authentication Code), которая позволяет убедиться, что сообщение:
Если значения совпадают — сообщение считается подлинным
var key = sjcl.codec.utf8String.toBits("secret-key");
var message = "Important data";
var hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
var mac = hmac.encrypt(message);
Проверка:
var hmacVerify = new sjcl.misc.hmac(key, sjcl.hash.sha256);
var macCheck = hmacVerify.encrypt(message);
if (sjcl.bitArray.equal(mac, macCheck)) {
console.log("Сообщение подлинное");
}
Современный подход — объединение шифрования и аутентификации. SJCL поддерживает режимы, обеспечивающие оба свойства одновременно.
SJCL использует AES-CCM как основной режим аутентифицированного шифрования.
Особенности:
var password = "strong-password";
var plaintext = "Sensitive message";
var encrypted = sjcl.encrypt(password, plaintext);
Результат содержит:
Расшифровка автоматически включает проверку:
try {
var decrypted = sjcl.decrypt(password, encrypted);
console.log("Сообщение корректно:", decrypted);
} catch (e) {
console.log("Ошибка аутентификации или повреждение данных");
}
Аутентификация напрямую зависит от управления ключами:
В контексте SJCL чаще используется симметричная модель, где:
В режиме CCM можно включать дополнительные аутентифицируемые данные (Additional Authenticated Data):
Это позволяет защищать метаданные:
var adata = sjcl.codec.utf8String.toBits("header-data");
var encrypted = sjcl.mode.ccm.encrypt(
new sjcl.cipher.aes(key),
plaintextBits,
iv,
adata,
128
);
Любое изменение AAD приведёт к ошибке проверки.
Для предотвращения повторной отправки сообщений применяются:
SJCL требует уникальности IV в режиме CCM:
var iv = sjcl.random.randomWords(3, 0);
Повторное использование IV с тем же ключом нарушает безопасность.
Некоторые реализации расшифровывают данные без проверки:
SJCL автоматически выбрасывает исключение — это поведение нельзя игнорировать
Сравнение MAC через обычные операции (==) может привести
к атаке по времени выполнения.
Правильный способ:
sjcl.bitArray.equal(a, b);
Полноценная схема выглядит так:
Генерация случайного IV
Шифрование сообщения (AES-CCM)
Добавление AAD (при необходимости)
Передача: ciphertext + IV + tag
Получатель:
Иногда используется схема:
В SJCL это можно реализовать вручную:
var ciphertext = sjcl.encrypt(password, message);
var hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
var mac = hmac.encrypt(ciphertext);
Получатель:
Надёжность проверки источника напрямую зависит от:
SJCL использует встроенный генератор:
sjcl.random.startCollectors();
Недостаток энтропии снижает устойчивость ко всем видам атак.
Любое зашифрованное сообщение должно проходить проверку:
Без этих гарантий шифрование теряет смысл, превращаясь лишь в средство сокрытия, но не защиты.