Симметричное шифрование основано на использовании одного и того же секретного ключа для выполнения двух взаимно обратных операций — шифрования и расшифрования. Это означает, что данные преобразуются в нечитабельный вид и затем возвращаются в исходное состояние с помощью одного и того же ключевого материала.
Симметричные алгоритмы строятся вокруг нескольких ключевых характеристик:
Единый секретный ключ Обе стороны, участвующие в обмене данными, используют один и тот же ключ. Его компрометация полностью разрушает безопасность схемы.
Высокая производительность Алгоритмы симметричного шифрования значительно быстрее асимметричных, что делает их основой для защиты больших объёмов данных.
Ограничение проблемы распределения ключей Основная сложность заключается не в вычислениях, а в безопасной передаче ключа между сторонами.
Детерминированность преобразований При одинаковых входных данных, ключе и параметрах алгоритма результат шифрования остаётся воспроизводимым.
В современных реализациях, включая CryptoJS, используются проверенные стандарты:
На практике именно AES используется как базовый механизм защиты данных.
Блочные алгоритмы, такие как AES, обрабатывают данные фиксированными блоками, поэтому используются режимы работы:
Каждый блок шифруется независимо.
Проблема заключается в том, что одинаковые блоки открытого текста дают одинаковые блоки шифртекста, что делает структуру данных уязвимой для анализа.
C_i = E_K(P_i C_{i-1})
Каждый блок зависит от результата предыдущего, что устраняет повторяемость шаблонов. Для первого блока используется вектор инициализации (IV).
Режимы потокового типа, позволяющие шифровать данные меньшими порциями без необходимости заполнения блоков.
Вектор инициализации используется для обеспечения уникальности шифрования при одинаковом ключе и одинаковых данных.
Ключевые свойства IV:
В CryptoJS IV обычно представляется как WordArray:
const iv = CryptoJS.lib.WordArray.random(16);
CryptoJS предоставляет реализацию AES и других алгоритмов в JavaScript без необходимости использования нативных криптографических API.
const ciphertext = CryptoJS.AES.encrypt(
"секретное сообщение",
"ключ"
).toString();
const bytes = CryptoJS.AES.decrypt(
ciphertext,
"ключ"
);
const originalText = bytes.toString(CryptoJS.enc.Utf8);
Криптографические алгоритмы работают с бинарными данными, поэтому в
CryptoJS используется абстракция WordArray.
Основные кодировки:
Пример преобразования:
const wordArray = CryptoJS.enc.Utf8.parse("данные");
const base64 = CryptoJS.enc.Base64.stringify(wordArray);
В CryptoJS строка ключа может интерпретироваться по-разному:
Прямое использование строки как ключа упрощает интерфейс, но снижает криптографическую устойчивость.
Для повышения безопасности используется функция вывода ключа из пароля:
const key = CryptoJS.PBKDF2("пароль", "соль", {
keySize: 256 / 32,
iterations: 1000
});
PBKDF2 увеличивает стоимость подбора ключа за счёт многократных итераций хэширования.
Соль используется для защиты от атак с предвычисленными таблицами (rainbow tables). Она добавляется к паролю перед обработкой.
const salt = CryptoJS.lib.WordArray.random(128 / 8);
Пример использования 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
});
При шифровании данных, длина которых не кратна размеру блока, используется дополнение:
PKCS7 добавляет байты, значение которых соответствует количеству добавленных байтов.
Симметричные алгоритмы делятся на:
CryptoJS преимущественно ориентирован на блочные алгоритмы, имитирующие потоковую обработку через режимы работы.
Безопасность симметричного шифрования зависит не только от алгоритма, но и от его использования.
Типовые ошибки:
Хэширование и симметричное шифрование решают разные задачи:
CryptoJS поддерживает оба подхода:
const hash = CryptoJS.SHA256("данные").toString();
Практическая схема защиты данных часто включает:
Такая комбинация обеспечивает многослойную защиту информации при корректной реализации криптографического протокола.