Библиотеки шифрования JavaScript: лучшие варианты
Сравните лучшие JS-библиотеки шифрования. От tweetnacl до libsodium.js — найдите подходящую для вашего проекта.
Лучшие JavaScript-библиотеки шифрования для передачи файлов в 2026 году: libsodium.js — для широкого охвата алгоритмов и скорости WASM; @noble/ciphers и @noble/curves — чистые JS-реализации с актуальными аудитами; tweetnacl — минимальный размер бандла с совместимыми NaCl-примитивами; crypto-js — только для устаревшего кода (избегайте в новых проектах); и нативный Web Crypto API — для всего, что он поддерживает. В этом руководстве сравниваются библиотеки по охвату алгоритмов, размеру бандла, истории аудитов, совместимости браузер/Node и реальной производительности при шифровании файлов. Выбор зависит от того, пишете ли вы под браузер или Node, нужен ли вам ChaCha20-Poly1305 или Argon2, и возможно ли уложиться в ограничения Web Crypto.
Сравнительная таблица
| Библиотека | Размер (gzip) | Backend | Ключевые алгоритмы | Аудит | Актуальность | |---|---|---|---|---|---| | Web Crypto API | 0 КБ (нативный) | Нативный браузер | AES-GCM, PBKDF2, RSA, ECDH, HMAC | Да (вендорами браузеров) | Да, но нет ChaCha/Argon2 | | libsodium.js | 200 КБ WASM / 400 КБ JS | WASM + JS-фолбэк | Всё из libsodium | Да (множественные) | Да | | @noble/ciphers | 8 КБ | Чистый JS | AES, ChaCha20, Poly1305, GCM-SIV | Да (Cure53 2023) | Да | | @noble/curves | 35 КБ | Чистый JS | Ed25519, X25519, secp256k1, BLS | Да (Trail of Bits, Cure53) | Да | | tweetnacl | 15 КБ | Чистый JS | Curve25519, Ed25519, XSalsa20-Poly1305 | Да (оригинальный аудит NaCl) | В основном, нет ChaCha20 | | crypto-js | 50 КБ | Чистый JS | AES-CBC, SHA, HMAC, PBKDF2 | Нет актуального аудита | Нет, не поддерживается с 2023 | | node:crypto | 0 КБ (нативный Node) | Node native (OpenSSL) | Широкий охват | Да (OpenSSL) | Да |
libsodium.js: универсальный инструмент
libsodium.js (сборка libsodium, скомпилированная через Emscripten) — выбор по умолчанию, когда Web Crypto недостаточно. Охватывает XChaCha20-Poly1305, Ed25519, X25519, Argon2id, BLAKE2b и API crypto_secretstream для потокового AEAD. WASM-сборка работает примерно на 50–70% от скорости нативного libsodium на типичном железе.
import _sodium from 'libsodium-wrappers';
await _sodium.ready;
const sodium = _sodium;
const key = sodium.crypto_secretstream_xchacha20poly1305_keygen();
const { state, header } = sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
const chunk = sodium.crypto_secretstream_xchacha20poly1305_push(
state, new Uint8Array([1,2,3]), null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE
);
Потоковый API — ключевое преимущество для передачи больших файлов. Можно шифровать 5-гигабайтный файл фрагмент за фрагментом, не загружая всё в память; каждый фрагмент несёт собственный тег аутентификации, поэтому повреждения обнаруживаются пофрагментно, а не только в конце.
Компромиссы: 200 КБ WASM — это много. Используйте динамические импорты (await import('libsodium-wrappers')), чтобы библиотека загружалась только при необходимости шифрования. Расширенная сборка (sumo, включает все алгоритмы) весит 600+ КБ; придерживайтесь стандартной сборки, если вам не нужны дополнительные функции.
@noble: компактность, аудит, современность
Семейство @noble от Пола Миллера (@noble/ciphers, @noble/curves, @noble/hashes) — современный эталон для чистого JS-крипто. Прошло аудит Cure53 (ciphers, 2023) и Trail of Bits (curves, 2022), нет зависимостей, поддерживается tree-shaking, нативный TypeScript.
import { gcm } from '@noble/ciphers/aes';
import { randomBytes } from '@noble/ciphers/webcrypto';
const key = randomBytes(32);
const nonce = randomBytes(12);
const ciphertext = gcm(key, nonce).encrypt(plaintext);
@noble не использует WASM, поэтому влияние на бандл минимально (8 КБ для ciphers). Производительность на 30–50% ниже, чем у WASM-версии libsodium для объёмного AES-GCM, но достаточна для большинства сценариев передачи. Подход с чистым JS означает идентичную работу в браузерах, Node, Deno, Bun и React Native без проблем с нативными модулями.
Выбирайте @noble, когда важен размер бандла, когда нужна tree-shakeable чистая JS-библиотека или когда используется платформа с ограниченной поддержкой WASM.
tweetnacl: минималистичный выбор
tweetnacl-js портирует библиотеку TweetNaCl Дэниела Бернштейна на JavaScript. 15 КБ в gzip. Покрывает обмен ключами Curve25519, подписи Ed25519 и аутентифицированное шифрование XSalsa20-Poly1305. Прошёл аудит в рамках оригинального проекта NaCl, хотя и не в последнее время.
import nacl from 'tweetnacl';
const key = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);
const ciphertext = nacl.secretbox(plaintext, nonce, key);
API намеренно минималистичен: если вам нужно больше, чем предоставляет NaCl (например, AES-GCM для совместимости с не-JS-системами), следует обратиться к другим вариантам. Для чистых NaCl-приложений tweetnacl по-прежнему остаётся разумным выбором, хотя @noble/ciphers плюс @noble/curves покрывают те же задачи с более актуальной поддержкой.
crypto-js: не используйте в новом коде
crypto-js доминировал в браузерном крипто в 2015 году. В 2026-м он является обузой. Последний значимый релиз — 2021 год (4.1.1); репозиторий фактически архивирован в 2023-м. По умолчанию использует AES-CBC с небезопасной деривацией ключей из паролей (схема OpenSSL EVP_BytesToKey), которая выводит ключи через несколько раундов MD5. CVE-2023-46233 зафиксировал слабые настройки PBKDF2 по умолчанию.
Если вы поддерживаете устаревший код на crypto-js, миграция на @noble/ciphers или Web Crypto несложна и оправдана. Если вы начинаете новый проект в 2026 году, пропустите crypto-js полностью.
node:crypto для серверного кода
Встроенный модуль crypto в Node оборачивает OpenSSL и имеет наиболее широкий охват алгоритмов из всех перечисленных вариантов. На Node 18+, require('crypto').webcrypto предоставляет совместимый с Web Crypto API, поэтому изоморфный код работает и на сервере, и на клиенте.
import { createCipheriv, randomBytes } from 'crypto';
const key = randomBytes(32);
const iv = randomBytes(12);
const cipher = createCipheriv('aes-256-gcm', key, iv);
const ct = Buffer.concat([cipher.update(plaintext), cipher.final()]);
const tag = cipher.getAuthTag();
Для серверного расшифрования файлов, зашифрованных Web Crypto, это наиболее чистый путь. Если ваш сервис передачи файлов расшифровывает что-либо на сервере (редко в конструкциях с нулевым знанием, но часто в устаревших системах при миграции на шифрование), используйте node:crypto.
Производительность на реальных задачах шифрования
Тесты на MacBook Air M2 при шифровании буфера 100 МБ с AES-256-GCM:
- Web Crypto API (Chrome 120): 340 мс (аппаратное ускорение)
- Web Crypto API (Safari 17): 280 мс (аппаратное ускорение на Apple Silicon)
- libsodium.js WASM: 420 мс
- @noble/ciphers: 1 850 мс (без аппаратного ускорения в чистом JS)
- tweetnacl (XSalsa20): 1 200 мс
- node:crypto: 180 мс (нативный OpenSSL)
Вывод: Web Crypto выигрывает для больших файлов, так как использует AES-NI. Чистый JS вполне подходит для малых данных, но добавляет секунды к многогигабайтным передачам. Для загрузки 5 ГБ разница между Web Crypto и @noble/ciphers может составить 2 против 10 минут времени шифрования.
Хеширование паролей: Argon2 или ничего
PBKDF2 — это минимум, но Argon2id лучше. Варианты:
- argon2-browser: скомпилированная в WASM эталонная реализация, 200 КБ.
- @noble/hashes: чистый JS Argon2id, 15 КБ, медленнее, но без WASM.
- libsodium.js: Argon2id через
crypto_pwhash, 200 КБ, но он уже есть, если используете libsodium.
Используйте Argon2id с минимум 3 итерациями, 64 МиБ памяти и 4 степенями параллелизма для ключей шифрования, производных от пароля, в браузерных контекстах (руководство OWASP 2024).
Выбор под вашу задачу
- Простая передача файлов с шифрованием AES-GCM: используйте Web Crypto напрямую, без библиотек. HexaTransfer следует именно этому подходу.
- Нужен ChaCha20-Poly1305 или потоковый AEAD: libsodium.js.
- Осторожность насчёт WASM или ограниченные бандлеры: @noble/ciphers + @noble/curves.
- Протоколы NaCl-ключей (например, sealed boxes для получения зашифрованных файлов): @noble или libsodium, не crypto-js.
- Миграция с crypto-js: переходите на @noble при важности размера бандла, иначе на libsodium.js.
- Постквантовые подписи или KEM: зрелых JS-библиотек пока нет; проверьте @noble/post-quantum (предварительный релиз в начале 2026 года).
Признаки качественного аудита и поддержки
Перед принятием крипто-библиотеки проверьте:
- Дата последнего коммита (всё, что старше 18 месяцев — риск).
- Публичные отчёты об аудите (Cure53, Trail of Bits, NCC Group).
- Трекер проблем на предмет нерешённых уязвимостей.
- Количество зависимостей (меньше = меньше поверхность атаки).
- Еженедельные загрузки на npm (больше = больше глаз на код).
В экосистеме JavaScript были инциденты с цепочкой поставок (event-stream, ua-parser-js, colors), которые делают минимальные зависимости свойством безопасности. Крипто-библиотеки без рантаймовых зависимостей (семейство @noble, tweetnacl) проще проверить от начала до конца, чем те, что подтягивают полифиллы и утилиты.
Попробуйте на hexatransfer.com — бесплатно, без регистрации, до 10 ГБ.
Безопасная отправка больших файлов со сквозным шифрованием
Передавайте файлы до 10 ГБ бесплатно со сквозным шифрованием. Регистрация не требуется. Ваши файлы шифруются в браузере перед загрузкой — никто другой не может их прочитать.
Отправить файл