Принципы симметричного шифрования

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

Симметричные алгоритмы строятся вокруг нескольких ключевых характеристик:

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

Высокая производительность Алгоритмы симметричного шифрования значительно быстрее асимметричных, что делает их основой для защиты больших объёмов данных.

Ограничение проблемы распределения ключей Основная сложность заключается не в вычислениях, а в безопасной передаче ключа между сторонами.

Детерминированность преобразований При одинаковых входных данных, ключе и параметрах алгоритма результат шифрования остаётся воспроизводимым.

Базовые криптографические алгоритмы

В современных реализациях, включая CryptoJS, используются проверенные стандарты:

  • AES (Advanced Encryption Standard) — основной стандарт симметричного шифрования
  • DES / 3DES — устаревшие алгоритмы, встречаются в легаси-системах
  • RC4 — потоковый шифр, считается небезопасным в современных условиях

На практике именно AES используется как базовый механизм защиты данных.

Режимы работы блочных шифров

Блочные алгоритмы, такие как AES, обрабатывают данные фиксированными блоками, поэтому используются режимы работы:

ECB (Electronic Codebook)

Каждый блок шифруется независимо.

Проблема заключается в том, что одинаковые блоки открытого текста дают одинаковые блоки шифртекста, что делает структуру данных уязвимой для анализа.

CBC (Cipher Block Chaining)

C_i = E_K(P_i C_{i-1})

Каждый блок зависит от результата предыдущего, что устраняет повторяемость шаблонов. Для первого блока используется вектор инициализации (IV).

CFB и OFB

Режимы потокового типа, позволяющие шифровать данные меньшими порциями без необходимости заполнения блоков.

Вектор инициализации (IV)

Вектор инициализации используется для обеспечения уникальности шифрования при одинаковом ключе и одинаковых данных.

Ключевые свойства IV:

  • не обязан быть секретным
  • должен быть уникальным для каждого шифрования
  • предотвращает повторяемость шифртекста

В CryptoJS IV обычно представляется как WordArray:

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

Библиотека CryptoJS и симметричное шифрование

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

Базовое шифрование AES

const ciphertext = CryptoJS.AES.encrypt(
    "секретное сообщение",
    "ключ"
).toString();

Расшифрование

const bytes = CryptoJS.AES.decrypt(
    ciphertext,
    "ключ"
);

const originalText = bytes.toString(CryptoJS.enc.Utf8);

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

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

Основные кодировки:

  • UTF-8 — текстовые строки
  • Base64 — представление бинарных данных
  • Hex — шестнадцатеричный формат

Пример преобразования:

const wordArray = CryptoJS.enc.Utf8.parse("данные");
const base64 = CryptoJS.enc.Base64.stringify(wordArray);

Использование ключей и их интерпретация

В CryptoJS строка ключа может интерпретироваться по-разному:

  • как сырой пароль
  • как бинарный ключ
  • как результат функции деривации

Прямое использование строки как ключа упрощает интерфейс, но снижает криптографическую устойчивость.

PBKDF2 и вывод ключа

Для повышения безопасности используется функция вывода ключа из пароля:

const key = CryptoJS.PBKDF2("пароль", "соль", {
    keySize: 256 / 32,
    iterations: 1000
});

PBKDF2 увеличивает стоимость подбора ключа за счёт многократных итераций хэширования.

Соль и её роль

Соль используется для защиты от атак с предвычисленными таблицами (rainbow tables). Она добавляется к паролю перед обработкой.

const salt = CryptoJS.lib.WordArray.random(128 / 8);

Режим CBC в CryptoJS

Пример использования AES в режиме CBC с явным указанием IV:

const key = CryptoJS.enc.Utf8.parse("my-secret-key-123");
const iv = CryptoJS.lib.WordArray.random(16);

const encrypted = CryptoJS.AES.encrypt("данные", key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

Расшифрование:

const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

Заполнение блоков (Padding)

При шифровании данных, длина которых не кратна размеру блока, используется дополнение:

  • Pkcs7 — наиболее распространённый вариант
  • NoPadding — требует строгого соответствия размера
  • Iso10126 — менее распространённый стандарт

PKCS7 добавляет байты, значение которых соответствует количеству добавленных байтов.

Потоковое и блочное шифрование

Симметричные алгоритмы делятся на:

  • блочные (AES, DES)
  • потоковые (RC4, Salsa20)

CryptoJS преимущественно ориентирован на блочные алгоритмы, имитирующие потоковую обработку через режимы работы.

Криптографическая стойкость и ошибки реализации

Безопасность симметричного шифрования зависит не только от алгоритма, но и от его использования.

Типовые ошибки:

  • повторное использование IV
  • хранение ключа в открытом виде
  • использование слабых паролей без PBKDF2
  • ECB-режим в чувствительных данных
  • отсутствие соли при деривации ключа

Хэширование и симметричное шифрование

Хэширование и симметричное шифрование решают разные задачи:

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

CryptoJS поддерживает оба подхода:

const hash = CryptoJS.SHA256("данные").toString();

Совместное использование компонентов CryptoJS

Практическая схема защиты данных часто включает:

  • PBKDF2 для генерации ключа
  • AES для шифрования
  • случайный IV
  • соль для усиления стойкости

Такая комбинация обеспечивает многослойную защиту информации при корректной реализации криптографического протокола.