Криптографические функции отличаются от обычной бизнес-логики тем, что ошибка в них приводит не к сбою интерфейса, а к компрометации безопасности данных. В случае с Stanford JavaScript Crypto Library (SJCL) тестирование становится не вспомогательным этапом разработки, а обязательной частью жизненного цикла каждой функции.
Основная цель юнит-тестирования криптографических компонентов — гарантировать детерминированность результатов, устойчивость к регрессиям и соответствие эталонным реализациям алгоритмов.
В экосистеме SJCL тесты строятся вокруг нескольких уровней проверки:
Типичная структура тестового набора включает:
Хеш-функции в SJCL (например SHA-256) проверяются через заранее известные тест-векторы.
const sjcl = require('sjcl');
const input = "hello";
const expected = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
const hash = sjcl.hash.sha256.hash(input);
const result = sjcl.codec.hex.fromBits(hash);
if (result !== expected) {
throw new Error("SHA-256 не совпадает с эталоном");
}
Ключевой принцип здесь — использование фиксированных входных данных и строгого сравнения с официальными векторами NIST.
Тестирование AES требует проверки не только шифрования, но и обратного преобразования.
const key = sjcl.codec.hex.toBits("000102030405060708090a0b0c0d0e0f");
const plaintext = sjcl.codec.utf8String.toBits("test data");
const aes = new sjcl.cipher.aes(key);
const ciphertext = aes.encrypt(plaintext);
const decrypted = aes.decrypt(ciphertext);
const decryptedText = sjcl.codec.utf8String.fromBits(decrypted);
if (decryptedText !== "test data") {
throw new Error("AES decryption failed");
}
Особое внимание уделяется:
Режим CBC проверяется на корректную обработку цепочек блоков.
const iv = sjcl.random.randomWords(4);
const mode = new sjcl.mode.cbc(aes);
const enc = mode.encrypt(plaintext, iv);
const dec = mode.decrypt(enc, iv);
Основные тестовые сценарии:
Аутентифицированные режимы требуют дополнительной проверки целостности данных.
Проверяется:
В SJCL используется криптографически стойкий генератор случайных чисел, основанный на AES-CTR.
Юнит-тесты здесь не проверяют «случайность» напрямую, а фокусируются на:
sjcl.random.addEntropy([1,2,3,4], 128);
const r1 = sjcl.random.randomWords(4);
const r2 = sjcl.random.randomWords(4);
if (sjcl.codec.hex.fromBits(r1) === sjcl.codec.hex.fromBits(r2)) {
throw new Error("Повторяющиеся случайные значения");
}
Функция PBKDF2 используется для получения ключей из паролей и требует особой точности.
Основные проверки:
const derived = sjcl.misc.pbkdf2("password", "salt", 1000, 256);
const hex = sjcl.codec.hex.fromBits(derived);
Сравнение проводится с заранее вычисленными значениями.
Криптографические библиотеки обязаны корректно обрабатывать ошибочные входные данные.
Проверяются сценарии:
try {
aes.decrypt([]);
throw new Error("Ожидалась ошибка");
} catch (e) {
// корректное поведение
}
SJCL активно использует разные форматы представления:
Юнит-тесты проверяют обратимость преобразований:
const bits = sjcl.codec.utf8String.toBits("data");
const base64 = sjcl.codec.base64.fromBits(bits);
const restored = sjcl.codec.utf8String.fromBits(
sjcl.codec.base64.toBits(base64)
);
if (restored !== "data") {
throw new Error("Ошибка кодирования/декодирования");
}
Криптографические функции тестируются на:
Цель — выявление переполнений, утечек памяти и деградации производительности.
Каждое изменение в криптографическом ядре требует повторной проверки всех эталонных векторов.
Типичный подход:
Для исключения влияния внешних факторов тесты выполняются в контролируемой среде:
Обычно используется интеграция с:
Пример структуры теста:
describe("AES tests", function () {
it("encrypt/decrypt cycle", function () {
const aes = new sjcl.cipher.aes(key);
const enc = aes.encrypt(plaintext);
const dec = aes.decrypt(enc);
assert.equal(
sjcl.codec.hex.fromBits(dec),
sjcl.codec.hex.fromBits(plaintext)
);
});
});
В криптографических библиотеках оцениваются:
JavaScript накладывает специфические ограничения:
Поэтому тестирование SJCL ориентировано не только на алгоритмы, но и на поведение в различных средах выполнения.