Encrypt: примеры (JAVASCRIPT)
encrypt(algorithm (object, string), key (CryptoKey), data (BufferSource)): PromiseМетод encrypt в Web Crypto API
В JavaScript нет глобальной функции с именем encrypt. Однако, в современных браузерах и средах, таких как Node.js, доступен Web Crypto API, который предоставляет метод subtle.encrypt() для выполнения криптографических операций шифрования.
Метод encrypt() используется для преобразования открытых данных (plaintext) в зашифрованный формат (ciphertext) с использованием симметричного или асимметричного алгоритма и ключа. Он является частью интерфейса SubtleCrypto и доступен через crypto.subtle.
Синтаксис:
const result = await crypto.subtle.encrypt(algorithm, key, data);
Аргументы:
- algorithm: объект, определяющий алгоритм шифрования и его параметры. Например:
{ name: "AES-GCM", iv: initializationVector }для AES-GCM или{ name: "RSA-OAEP" }для RSA-OAEP. - key: объект
CryptoKey, содержащий ключ, который будет использоваться для шифрования. Ключ должен иметь разрешение["encrypt"]. - data:
ArrayBuffer,TypedArrayилиDataView, представляющий данные для шифрования.
Возвращаемое значение: Промис, который разрешается в ArrayBuffer, содержащий зашифрованные данные (ciphertext). В случае ошибки промис отклоняется.
Простые примеры шифрования
Шифрование с использованием алгоритма AES-GCM.
// Генерация ключа и IV (Initialization Vector)
async function exampleAESGCM() {
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const data = new TextEncoder().encode("Секретное сообщение");
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv: iv },
key,
data
);
console.log(new Uint8Array(encrypted));
}
exampleAESGCM();// Результат (зависит от ключа и IV): // Uint8Array(48) [65, 123, 234, ...] // Пример вывода зашифрованных байтов
Шифрование с использованием алгоритма RSA-OAEP.
async function exampleRSAOAEP() {
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
const data = new TextEncoder().encode("Данные для шифрования");
const encrypted = await crypto.subtle.encrypt(
{ name: "RSA-OAEP" },
keyPair.publicKey,
data
);
console.log(new Uint8Array(encrypted));
}
exampleRSAOAEP();// Результат (зависит от ключа): // Uint8Array(256) [12, 45, 198, ...] // Зашифрованные данные фиксированного размера для RSA 2048
Альтернативы в JavaScript
- CryptoJS: популярная библиотека, предоставляющая упрощенный API для различных алгоритмов шифрования. Подходит для сред, где Web Crypto API недоступен (например, старые браузеры). Работает с строками и предоставляет функции вроде
CryptoJS.AES.encrypt("сообщение", "пароль"). - Node.js crypto module: в среде Node.js встроенный модуль
cryptoпредлагает синхронные и асинхронные методы, такие какcrypto.createCipheriv()иcrypto.publicEncrypt(). Он более гибкий и поддерживает множество алгоритмов.
Web Crypto API предпочтительнее для веб-приложений из-за интеграции с браузером и безопасности. CryptoJS удобна для простых сценариев или legacy-проектов. Модуль Node.js crypto — стандартный выбор для серверной разработки на Node.js.
Альтернативы в других языках
Python (cryptography):
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os
key = os.urandom(32)
iv = os.urandom(12)
cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend())
encryptor = cipher.encryptor()
ciphertext = encryptor.update(b"secret data") + encryptor.finalize()
print(ciphertext)# b'...' # Байтовая строка с зашифрованными данными
PHP (openssl_encrypt):
$data = "secret data";
$key = openssl_random_pseudo_bytes(32);
$iv = openssl_random_pseudo_bytes(12);
$ciphertext = openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo bin2hex($ciphertext);// Выведет шестнадцатеричное представление зашифрованных данных
Отличия: в Python и PHP часто используются библиотеки, а не встроенное API. Синтаксис отличается, но концепции (алгоритм, ключ, IV) схожи. Web Crypto API является асинхронным, в то время как многие функции в PHP и Python — синхронные.
Типичные ошибки
1. Использование неверного типа данных для аргумента data.
// Ошибка: data должна быть ArrayBuffer, TypedArray или DataView
async function errorExample() {
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const data = "Строка, а не ArrayBuffer"; // Ошибка!
try {
await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, data);
} catch (e) {
console.error(e.message);
}
}
errorExample();// TypeError: Provided data is not an ArrayBuffer, a TypedArray or a DataView
2. Несоответствие алгоритма при шифровании и расшифровке.
async function errorExample2() {
const key = await crypto.subtle.generateKey(
{ name: "AES-CBC", length: 256 },
true,
["encrypt", "decrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(16));
const data = new TextEncoder().encode("test");
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-CBC", iv },
key,
data
);
// Попытка расшифровать с другим алгоритмом или параметром
try {
await crypto.subtle.decrypt(
{ name: "AES-GCM", iv }, // Ошибка: другой алгоритм
key,
encrypted
);
} catch (e) {
console.error(e.message);
}
}
errorExample2();// Error: Алгоритм шифрования и расшифровки не совпадают
Изменения в Web Crypto API
Web Crypto API является относительно стабильным стандартом. Существенных изменений в методе encrypt в последних версиях не было. Однако, поддержка определенных алгоритмов может расширяться. Например, алгоритм AES-KW (Key Wrap) был добавлен для специфичных случаев обмена ключами. Рекомендуется проверять таблицы совместимости браузеров для использования новейших функций.
В Node.js модуль crypto постоянно развивается. В последних версиях Node.js улучшена поддержка асинхронных операций и добавлены новые алгоритмы, такие как ChaCha20-Poly1305.
Расширенные примеры использования
Шифрование с аутентификацией данных (AEAD) используя AES-GCM с дополнительными аутентифицированными данными (AAD).
async function encryptWithAAD() {
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const data = new TextEncoder().encode("Конфиденциальные данные");
const aad = new TextEncoder().encode("Метаданные, которые нужно аутентифицировать");
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv: iv, additionalData: aad },
key,
data
);
console.log("Зашифрованные данные:", new Uint8Array(encrypted));
}
encryptWithAAD();// Зашифрованные данные: Uint8Array(60) [ ... ] // Размер включает ciphertext и аутентификационный тег
Шифрование с использованием алгоритма RSA-PSS (обычно для подписей, но демонстрация работы с асимметричным шифрованием).
async function encryptLargeData() {
// Генерация ключевой пары RSA-OAEP
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-512"
},
true,
["encrypt", "decrypt"]
);
// RSA может шифровать только данные ограниченного размера.
// Для больших данных используют гибридное шифрование.
const sessionKey = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
// Экспортируем сырой ключ сессии и шифруем его RSA-OAEP
const exportedSessionKey = await crypto.subtle.exportKey("raw", sessionKey);
const encryptedSessionKey = await crypto.subtle.encrypt(
{ name: "RSA-OAEP" },
keyPair.publicKey,
exportedSessionKey
);
console.log("Зашифрованный сессионный ключ:", new Uint8Array(encryptedSessionKey));
}
encryptLargeData();// Зашифрованный сессионный ключ: Uint8Array(512) [ ... ] // Для RSA 4096