Одна из самых частых проблем при работе с SJCL связана с тем, что
большинство разработчиков ожидают, что библиотека оперирует строками или
Uint8Array, тогда как базовый тип данных в SJCL — это
bitArray.
bitArray представляет собой массив 32-битных слов с
дополнительным указанием длины в битах. Это критически важно:
Ошибка возникает, когда bitArray воспринимается как
обычный массив чисел:
const hash = sjcl.hash.sha256.hash("test");
console.log(hash.length); // не длина в байтах!
Правильная интерпретация требует использования кодеков:
const hex = sjcl.codec.hex.fromBits(hash);
sjcl.codecSJCL строго разделяет внутренний формат и представление данных. Любая попытка вручную преобразовать данные приводит к ошибкам.
Распространённые ошибки:
toString() вместо
sjcl.codec.*const encrypted = sjcl.encrypt("password", "data");
console.log(encrypted.toString()); // бессмысленный результат
const encrypted = sjcl.encrypt("password", "data");
const parsed = JSON.parse(encrypted);
SJCL не предполагает автоматической нормализации строк. Любая строка
преобразуется в битовый массив через utf8String.
Проблемы возникают в следующих случаях:
Ошибка:
sjcl.hash.sha256.hash("café");
sjcl.hash.sha256.hash("cafe\u0301"); // другой результат
Хотя визуально строки одинаковы, байтовое представление различается.
При работе с hex и base64 кодеками часто
возникает ошибка обрезки ведущих нулей.
const bits = sjcl.codec.hex.toBits("0a");
const back = sjcl.codec.hex.fromBits(bits);
Результат может неожиданно стать "a" вместо
"0a".
Это связано с тем, что hex-строка интерпретируется как число, а не как фиксированная длина байтового массива.
bitArrayОбычная операция:
const a = sjcl.codec.utf8String.toBits("hello");
const b = sjcl.codec.utf8String.toBits("world");
const c = a.concat(b);
Проблема заключается в том, что concat в SJCL:
Ошибка проявляется при повторном использовании a или
b после конкатенации.
Каждый bitArray хранит длину в последнем элементе.
Игнорирование этого приводит к:
Типичная ошибка:
const bits = sjcl.codec.utf8String.toBits("data");
bits.pop(); // разрушение структуры
Любая модификация массива вручную приводит к некорректной работе криптографических функций.
SJCL использует блочные шифры, где входные данные должны быть корректно выровнены.
Распространённые ошибки:
bitArrayПример некорректного использования:
sjcl.encrypt("key", "short");
Хотя API допускает строки, при низкоуровневом использовании возникает рассинхронизация форматов.
bitArray не сериализуется напрямую:
JSON.stringify(sjcl.hash.sha256.hash("test")); // потеря структуры
После десериализации восстановить исходные данные невозможно без кодека.
Правильный способ:
const hex = sjcl.codec.hex.fromBits(bits);
JSON.stringify(hex);
SJCL предоставляет криптографически стойкий генератор:
sjcl.random.randomWords(4);
Ошибка возникает, когда:
Разные компоненты SJCL ожидают разные представления:
sjcl.hash → bitArraysjcl.encrypt → строка или bitArraysjcl.codec.* → конвертерыОшибка возникает при смешивании:
const hash = sjcl.hash.sha256.hash("data");
sjcl.encrypt("key", hash); // некорректное использование
Правильный путь:
const hex = sjcl.codec.hex.fromBits(hash);
sjcl.encrypt("key", hex);
SJCL использует стандартный base64, но часто данные приходят в base64url.
Отличия:
+ и / vs - и
_=Ошибка возникает при прямой передаче:
sjcl.codec.base64.toBits(base64url); // некорректно
Необходима предварительная нормализация строки.
bitArray передаётся по ссылке. Любая операция над ним
может изменить исходные данные:
const a = sjcl.codec.utf8String.toBits("test");
const b = a;
b[0] = 0; // изменяет a
Это приводит к:
JavaScript разработчики часто ожидают:
Uint8ArraySJCL же работает строго:
bitArrayЛюбая попытка “упростить” приводит к скрытым ошибкам, которые проявляются только на этапе дешифрования или проверки подписи.