Encrypt: примеры (JAVASCRIPT)

Использование функции encrypt для шифрования в JavaScript
Раздел: Crypto, Шифрование
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).

Пример javascript
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 (обычно для подписей, но демонстрация работы с асимметричным шифрованием).

Пример javascript
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

JS encrypt function comments

En
Encrypt Encrypts data using a cryptographic algorithm