Работа с hex-строками в CryptoJS строится вокруг базовой сущности
библиотеки — WordArray. Любые бинарные данные внутри
CryptoJS представлены массивом 32-битных слов (words) и
количеством значащих байт (sigBytes). Hex-формат выступает
одним из стандартных способов сериализации этого внутреннего
представления в человекочитаемую строку и обратно.
Внутренний формат CryptoJS не оперирует байтовыми массивами напрямую. Основная структура:
words — массив 32-битных целых чиселsigBytes — количество значимых байтHex-строка является просто текстовым отображением этих байтов, где каждый байт кодируется двумя шестнадцатеричными символами.
Пример соответствия:
0x0f → строка "0f"0xa3 → строка "a3"Таким образом, длина hex-строки всегда кратна двум.
Для сериализации используется модуль CryptoJS.enc.Hex и
метод stringify.
import CryptoJS from "crypto-js";
const wordArray = CryptoJS.enc.Utf8.parse("data");
const hexString = CryptoJS.enc.Hex.stringify(wordArray);
console.log(hexString);
В результате каждый байт исходной строки преобразуется в два hex-символа.
sigBytesПример:
const wa = CryptoJS.enc.Hex.parse("01020304");
CryptoJS.enc.Hex.stringify(wa); // "01020304"
Обратная операция выполняется через parse.
const wordArray = CryptoJS.enc.Hex.parse("deadbeef");
На выходе формируется структура:
words = [0xdeadbeef]sigBytes = 4Hex-строка должна содержать чётное количество символов. Каждый байт кодируется двумя символами.
Нечётная строка:
CryptoJS.enc.Hex.parse("abc"); // некорректный случай
Корректная форма требует:
CryptoJS.enc.Hex.parse("0abc");
Ключевая особенность CryptoJS заключается в том, что значимость
данных определяется не содержимым массива words, а
параметром sigBytes.
Рассмотрим ситуацию:
const wa = CryptoJS.enc.Hex.parse("0001");
CryptoJS.enc.Hex.stringify(wa);
Результат:
"0001"
Однако при некорректных преобразованиях через числа возможна потеря ведущих нулей:
const wa = CryptoJS.lib.WordArray.create([1], 1);
CryptoJS.enc.Hex.stringify(wa);
Результат:
"01"
Если исходная длина была 2 байта (0001), то
sigBytes должен это отражать. Иначе происходит усечение
данных.
Каждое 32-битное слово хранит 4 байта:
0x11223344 → байты: 11 22 33 44
Hex-строка формируется последовательной записью байтов:
[0x11][0x22][0x33][0x44] → "11223344"
При этом порядок байтов внутри слова соответствует big-endian логике представления CryptoJS, что часто становится источником ошибок при взаимодействии с Node.js Buffer или ArrayBuffer.
Большинство криптографических функций CryptoJS возвращают
WordArray, который по умолчанию отображается в hex при
вызове .toString().
const hash = CryptoJS.SHA256("message");
console.log(hash.toString());
Выход:
64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232b3f8b6d6c3a8c3
Явное указание кодировщика:
hash.toString(CryptoJS.enc.Hex);
Фактически эквивалентно, так как hex является стандартным представлением.
При работе с бинарными протоколами часто встречаются строки переменной длины:
const input = "a1b2c3d4e5f6";
const wa = CryptoJS.enc.Hex.parse(input);
Каждая пара символов интерпретируется как байт.
Если длина строки не кратна 2, необходимо нормализовать вход:
function normalizeHex(hex) {
return hex.length % 2 === 0 ? hex : "0" + hex;
}
В экосистеме Node.js hex часто используется вместе с
Buffer.
Эквивалентные операции:
const buffer = Buffer.from("deadbeef", "hex");
CryptoJS эквивалент:
const wa = CryptoJS.enc.Hex.parse("deadbeef");
Обратное преобразование:
buffer.toString("hex");
CryptoJS.enc.Hex.stringify(wa);
Различие заключается в том, что Buffer работает с байтовыми массивами напрямую, тогда как CryptoJS использует промежуточный WordArray.
Hex-строки могут быть как в нижнем, так и в верхнем регистре:
deadbeef
DEADBEEF
CryptoJS не различает регистр при парсинге:
CryptoJS.enc.Hex.parse("DEADBEEF");
CryptoJS.enc.Hex.parse("deadbeef");
Однако при сериализации результат всегда формируется в нижнем регистре.
Hex часто используется как внешний формат для ключей, IV и подписи.
Пример AES:
const key = CryptoJS.enc.Hex.parse("00112233445566778899aabbccddeeff");
const iv = CryptoJS.enc.Hex.parse("0102030405060708");
const encrypted = CryptoJS.AES.encrypt("data", key, {
iv: iv
});
const ciphertextHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
Здесь:
Наиболее частые проблемы связаны с несоответствием длины и интерпретации байтов:
Утрата ведущих нулей
Нечётная длина строки
Несоответствие endianness
Игнорирование sigBytes
Hex часто выступает промежуточным форматом между бинарными и текстовыми представлениями.
const utf8 = CryptoJS.enc.Utf8.parse("text");
const hex = CryptoJS.enc.Hex.stringify(utf8);
const back = CryptoJS.enc.Hex.parse(hex);
При корректной работе цепочка преобразований сохраняет исходные данные без потерь.
Типичный поток данных в криптографических задачах:
const input = "hello";
const wa = CryptoJS.enc.Utf8.parse(input);
const hash = CryptoJS.SHA256(wa);
const hex = hash.toString(CryptoJS.enc.Hex);
sigBytes