Кодировки и пространство имён CryptoJS.enc

В библиотеке CryptoJS модуль enc отвечает за преобразование данных между различными представлениями. Все криптографические операции внутри CryptoJS работают с внутренним типом данных WordArray, поэтому любые входные и выходные значения должны быть корректно закодированы или декодированы.

Пространство имён CryptoJS.enc содержит набор кодировщиков (encoders), каждый из которых реализует два базовых метода:

  • parse(string) — преобразует строку в WordArray
  • stringify(wordArray) — преобразует WordArray обратно в строку

Это позволяет гибко управлять представлением данных при шифровании, хэшировании и других операциях.


Внутренний формат: WordArray

WordArray — ключевая структура данных в CryptoJS. Она представляет собой массив 32-битных слов (words) и длину в байтах (sigBytes).

Пример структуры:

{
  words: [0x12345678, 0x90abcdef],
  sigBytes: 8
}

Особенности:

  • Каждый элемент массива words содержит 4 байта
  • sigBytes указывает фактическое количество значимых байтов
  • Используется во всех алгоритмах: AES, SHA, HMAC и др.

Кодировка UTF-8 (CryptoJS.enc.Utf8)

Наиболее часто используемая кодировка для строк.

Преобразование строки в WordArray:

const wordArray = CryptoJS.enc.Utf8.parse("Hello");

Обратное преобразование:

const str = CryptoJS.enc.Utf8.stringify(wordArray);

Особенности:

  • Поддерживает многобайтовые символы (например, кириллицу)
  • Используется по умолчанию во многих методах (например, CryptoJS.SHA256("text"))

Кодировка Hex (CryptoJS.enc.Hex)

Представляет данные в шестнадцатеричном виде.

Пример:

const hash = CryptoJS.SHA256("Hello");
const hexString = hash.toString(CryptoJS.enc.Hex);

Результат:

185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

Обратное преобразование:

const wordArray = CryptoJS.enc.Hex.parse(hexString);

Особенности:

  • Удобна для хранения и передачи бинарных данных в текстовом виде
  • Часто используется для хэшей и ключей

Кодировка Base64 (CryptoJS.enc.Base64)

Используется для компактного текстового представления бинарных данных.

Пример:

const wordArray = CryptoJS.enc.Utf8.parse("Hello");
const base64 = CryptoJS.enc.Base64.stringify(wordArray);

Результат:

SGVsbG8=

Обратное преобразование:

const parsed = CryptoJS.enc.Base64.parse(base64);
const original = CryptoJS.enc.Utf8.stringify(parsed);

Особенности:

  • Широко используется в веб-протоколах (HTTP, JWT)
  • Компактнее Hex (меньше символов)

Кодировка Latin1 (CryptoJS.enc.Latin1)

Работает с однобайтовыми символами (ISO-8859-1).

Пример:

const wordArray = CryptoJS.enc.Latin1.parse("Hello");
const str = CryptoJS.enc.Latin1.stringify(wordArray);

Особенности:

  • Каждый символ занимает ровно 1 байт
  • Не подходит для Unicode (например, кириллицы)
  • Используется в специфичных сценариях совместимости

Кодировка Utf16 (CryptoJS.enc.Utf16)

Поддерживает 16-битные символы.

Пример:

const wordArray = CryptoJS.enc.Utf16.parse("Hello");
const str = CryptoJS.enc.Utf16.stringify(wordArray);

Особенности:

  • Каждый символ занимает 2 байта
  • Подходит для работы с Unicode
  • Используется реже, чем UTF-8

Использование кодировок в хэшировании

CryptoJS автоматически применяет UTF-8 при передаче строки:

const hash = CryptoJS.SHA256("Пример");

Эквивалентно:

const wordArray = CryptoJS.enc.Utf8.parse("Пример");
const hash = CryptoJS.SHA256(wordArray);

Вывод можно изменить:

hash.toString(CryptoJS.enc.Base64);
hash.toString(CryptoJS.enc.Hex);

Использование кодировок в шифровании

При шифровании строки:

const encrypted = CryptoJS.AES.encrypt("Secret", "key");

CryptoJS:

  1. Преобразует строку в UTF-8
  2. Шифрует данные
  3. Возвращает результат в Base64

Явное управление кодировкой:

const data = CryptoJS.enc.Utf8.parse("Secret");
const key = CryptoJS.enc.Hex.parse("00112233445566778899aabbccddeeff");

const encrypted = CryptoJS.AES.encrypt(data, key, {
  iv: CryptoJS.enc.Hex.parse("00000000000000000000000000000000")
});

Комбинирование кодировок

Возможна цепочка преобразований:

const utf8 = CryptoJS.enc.Utf8.parse("Hello");
const hex = CryptoJS.enc.Hex.stringify(utf8);
const base64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(hex));

Такие операции полезны при:

  • преобразовании форматов ключей
  • совместимости с внешними API
  • сериализации данных

Расширение: собственные кодировщики

CryptoJS позволяет создавать кастомные кодировщики:

CryptoJS.enc.Custom = {
  stringify: function (wordArray) {
    // логика преобразования
  },
  parse: function (str) {
    // обратная логика
  }
};

Требования:

  • stringify должен возвращать строку
  • parse должен возвращать WordArray

Типичные ошибки

1. Несоответствие кодировок

// Ошибка: строка интерпретируется неверно
CryptoJS.enc.Hex.parse("Привет");

2. Потеря данных при Latin1

CryptoJS.enc.Latin1.parse("Привет"); // некорректно

3. Двойное кодирование

const base64 = CryptoJS.enc.Base64.stringify(
  CryptoJS.enc.Utf8.parse("Hello")
);

Если затем снова применять parse/stringify без необходимости — возникает путаница.


Практические рекомендации

  • Для строк — использовать UTF-8
  • Для хэшей и ключей — Hex
  • Для передачи по сети — Base64
  • Избегать Latin1 без необходимости
  • Всегда контролировать входной и выходной формат

Связь с другими модулями CryptoJS

Модуль enc тесно интегрирован с:

  • CryptoJS.lib.WordArray
  • CryptoJS.algo.* (алгоритмы)
  • CryptoJS.format.* (форматы вывода)

Пример взаимодействия:

const hash = CryptoJS.algo.SHA256.create();
hash.update(CryptoJS.enc.Utf8.parse("data"));
const result = hash.finalize().toString(CryptoJS.enc.Hex);

Производительность и особенности

  • Преобразования parse и stringify — относительно дешёвые операции
  • Основные затраты приходятся на криптографические алгоритмы
  • Избыточные конверсии могут ухудшать читаемость кода

Ключевая роль CryptoJS.enc

Пространство имён CryptoJS.enc выполняет роль моста между:

  • строковыми данными (человекочитаемый формат)
  • бинарными данными (WordArray)
  • различными представлениями (Hex, Base64 и др.)

Без корректного понимания кодировок невозможно безопасно и предсказуемо использовать криптографические функции библиотеки.