Проверка целостности данных в контексте криптографии означает гарантию того, что полученное сообщение не было изменено в процессе передачи и действительно создано владельцем ключа. В Stanford JavaScript Crypto Library (SJCL) эта задача решается не отдельным механизмом, а встроенной моделью аутентифицированного шифрования и криптографических MAC.
Ключевая идея заключается в том, что шифрование без проверки подлинности не защищает от подмены: злоумышленник может модифицировать зашифрованный текст, не зная ключа, и это приведёт к непредсказуемым последствиям при расшифровке. Поэтому в SJCL используются режимы, совмещающие конфиденциальность и контроль целостности.
В библиотеке применяются два основных подхода:
Каждый из них решает задачу проверки целостности, но на разных уровнях.
HMAC используется, когда данные не шифруются, но требуется гарантировать их неизменность.
В SJCL он реализуется через sjcl.misc.hmac и
криптографические хеш-функции, например SHA-256:
const key = sjcl.codec.utf8String.toBits("secret-key");
const hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
const data = sjcl.codec.utf8String.toBits("message");
const tag = hmac.encrypt(data);
const valid = sjcl.bitArray.equal(
tag,
hmac.encrypt(data)
);
bitArray)sjcl.bitArray.equalHMAC применяется, когда шифрование не требуется, но нужна защита от подмены (например, для API-запросов или подписанных сообщений).
На практике чаще используется режим CCM (Counter with CBC-MAC), который объединяет шифрование и проверку целостности в одном процессе.
В SJCL это реализовано через sjcl.mode.ccm.
const key = sjcl.codec.utf8String.toBits("encryption-key");
const iv = sjcl.random.randomWords(4, 0);
const plaintext = "confidential data";
const encrypted = sjcl.encrypt(key, plaintext, {
mode: "ccm",
iv: iv,
ts: 64
});
Здесь ts (tag size) определяет размер
аутентификационного тега в битах.
Главная особенность SJCL заключается в том, что проверка целостности выполняется автоматически при расшифровке.
const decrypted = sjcl.decrypt(key, encrypted);
Если данные были изменены хотя бы на один бит, происходит одно из двух:
Это означает, что результат не просто “неправильный текст”, а полностью недоверенные данные.
Аутентифицированные режимы проверяют:
Любое расхождение делает данные недействительными.
SJCL оперирует не строками, а бинарным форматом
bitArray. Это важно, поскольку криптографические операции
чувствительны к побитовым изменениям.
const a = sjcl.codec.utf8String.toBits("abc");
const b = sjcl.codec.utf8String.toBits("abc");
sjcl.bitArray.equal(a, b); // true
При малейшем изменении:
const c = sjcl.codec.utf8String.toBits("abd");
sjcl.bitArray.equal(a, c); // false
Такой подход исключает ошибки, связанные с кодировками или строковыми преобразованиями.
В системах, где требуется явное управление процессом, HMAC используется отдельно от шифрования.
const key = sjcl.codec.utf8String.toBits("auth-key");
const hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
const message = sjcl.codec.utf8String.toBits("important message");
const signature = hmac.encrypt(message);
const incomingMessage = sjcl.codec.utf8String.toBits("important message");
const incomingSignature = signature;
const computed = hmac.encrypt(incomingMessage);
const isValid = sjcl.bitArray.equal(computed, incomingSignature);
Если сообщение изменено:
const tampered = sjcl.codec.utf8String.toBits("important messagE");
sjcl.bitArray.equal(
hmac.encrypt(tampered),
signature
); // false
В режимах типа CCM возможно добавление дополнительных аутентифицируемых данных, которые не шифруются, но участвуют в проверке целостности.
const encrypted = sjcl.encrypt(key, plaintext, {
mode: "ccm",
iv: iv,
adata: "header-data"
});
Эти данные:
Изменение adata делает сообщение недействительным.
При нарушении целостности SJCL не пытается “исправить” данные. Поведение строгое:
Это критично для защиты от атак типа:
В реальных приложениях используется следующая логика:
sjcl.decrypttry {
const data = sjcl.decrypt(key, payload);
} catch (e) {
// данные повреждены или подделаны
}
В SJCL эти две задачи не разделяются в современных режимах. Это принципиально:
Особенно это важно в CCM:
Такой подход делает невозможными целые классы ошибок:
Целостность в SJCL — это не дополнительный слой, а встроенное свойство криптографической операции, зависящее от корректности ключа и параметров режима.