Базовый тип WordArray

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

WordArray представляет собой объект со следующими ключевыми свойствами:

  • words — массив 32-битных целых чисел (каждое число = 4 байта)
  • sigBytes — количество значащих байтов в массиве

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

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

Здесь массив words содержит два 32-битных слова (в сумме 8 байт), а sigBytes указывает, что используются все 8 байт.


Представление данных

WordArray хранит данные в виде последовательности 32-битных слов, где каждый элемент массива words содержит 4 байта:

[ word0, word1, word2, ... ]

Каждое слово:

word = 0xAABBCCDD

Разбивается на байты:

AA BB CC DD

Порядок байтов — big-endian (старший байт первым).

Если количество байтов не кратно 4, используется sigBytes для указания фактической длины. Например:

CryptoJS.lib.WordArray.create([0x12345678], 3);

Означает, что используется только первые 3 байта:

12 34 56

Создание WordArray

Из массива слов

const wordArray = CryptoJS.lib.WordArray.create([0x12345678, 0x90abcdef], 8);

Если sigBytes не указан, он автоматически вычисляется как words.length * 4.


Из строки

CryptoJS автоматически преобразует строки в WordArray:

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

Внутренне строка кодируется в UTF-8 и затем упаковывается в слова.


Из случайных данных

const random = CryptoJS.lib.WordArray.random(16);

Создаёт WordArray длиной 16 байт с криптографически стойкими случайными значениями.


Преобразование WordArray

WordArray может быть преобразован в строку различными способами с помощью кодировщиков.

В hex-строку

const hex = wordArray.toString(CryptoJS.enc.Hex);

Результат:

"1234567890abcdef"

В Base64

const base64 = wordArray.toString(CryptoJS.enc.Base64);

В UTF-8 строку

const utf8 = wordArray.toString(CryptoJS.enc.Utf8);

Важно: корректно работает только если данные действительно являются UTF-8.


Конкатенация WordArray

Метод concat позволяет объединять массивы:

const wa1 = CryptoJS.enc.Hex.parse("1234");
const wa2 = CryptoJS.enc.Hex.parse("abcd");

wa1.concat(wa2);

Результат:

1234abcd

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

  • учитывается sigBytes
  • корректно обрабатываются неполные слова

Усечение данных (clamp)

Метод clamp() обрезает лишние биты в последнем слове:

wordArray.clamp();

Это необходимо, если количество байтов (sigBytes) не кратно 4. Метод:

  • удаляет лишние биты
  • уменьшает массив words, если нужно

Копирование

const clone = wordArray.clone();

Создаёт независимую копию объекта, включая массив words.


Работа с sigBytes

Поле sigBytes — ключевой элемент корректной работы WordArray.

Пример:

const wa = CryptoJS.lib.WordArray.create([0x12345678], 2);

Хотя слово содержит 4 байта, фактически используются только 2:

12 34

Если проигнорировать sigBytes, возможны ошибки:

  • лишние байты попадут в хеш
  • шифрование даст неверный результат

Внутренние оптимизации

WordArray оптимизирован под криптографические алгоритмы:

  • операции выполняются над 32-битными словами
  • уменьшается количество итераций
  • повышается производительность

Например, SHA-256 обрабатывает данные блоками по 512 бит (16 слов), поэтому WordArray идеально подходит для таких задач.


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

const hash = CryptoJS.SHA256("Hello");

Внутри:

  1. строка преобразуется в WordArray
  2. алгоритм работает с words
  3. результат — новый WordArray

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

const encrypted = CryptoJS.AES.encrypt("Hello", "password");

Процесс:

  • строка → WordArray
  • ключ → WordArray
  • результат → WordArray (ciphertext)

Кодировщики (Encoders)

CryptoJS предоставляет набор кодировщиков для работы с WordArray:

  • CryptoJS.enc.Hex
  • CryptoJS.enc.Utf8
  • CryptoJS.enc.Base64
  • CryptoJS.enc.Latin1

Каждый кодировщик реализует:

  • parse(string) → WordArray
  • stringify(wordArray) → строка

Особенности и подводные камни

1. Неправильная кодировка

CryptoJS.enc.Utf8.parse("Привет");

Важно учитывать, что UTF-8 кодирует символы переменной длиной.


2. Потеря данных при toString() Если не указать кодировщик:

wordArray.toString();

по умолчанию используется Hex.


3. Работа с бинарными данными WordArray не равен ArrayBuffer или Uint8Array. При интеграции с Web API требуется конвертация.


Пример полной работы

const data = "Hello World";

// строка → WordArray
const wa = CryptoJS.enc.Utf8.parse(data);

// WordArray → hex
const hex = wa.toString(CryptoJS.enc.Hex);

// hex → WordArray
const wa2 = CryptoJS.enc.Hex.parse(hex);

// обратно в строку
const result = wa2.toString(CryptoJS.enc.Utf8);

Сравнение с другими форматами

Тип Назначение Особенности
WordArray Внутренний формат CryptoJS 32-битные слова
Uint8Array Работа с бинарными API байтовый массив
String Текстовые данные требует кодировки

Роль в архитектуре CryptoJS

WordArray — фундаментальный уровень абстракции:

  • все алгоритмы принимают и возвращают WordArray
  • кодировщики преобразуют данные в/из WordArray
  • ключи и IV представлены как WordArray

Это делает библиотеку:

  • универсальной
  • производительной
  • расширяемой

Рекомендации по использованию

  • всегда явно указывать кодировку при преобразованиях
  • следить за sigBytes при ручной работе
  • использовать clone() при необходимости копирования
  • избегать прямой модификации words без понимания структуры

Итоговая модель работы

Строка → Encoder → WordArray → Алгоритм → WordArray → Encoder → Строка

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