Biblioteki szyfrowania JavaScript: najlepsze wybory
Porównaj najlepsze biblioteki szyfrowania JS dla web. Od tweetnacl do libsodium.js, znajdź odpowiednią dla swojego projektu.
Najlepsze biblioteki szyfrowania JavaScript do transferu pliku w 2026 roku to: libsodium.js — dla szerokiego pokrycia algorytmów i prędkości WASM; @noble/ciphers oraz @noble/curves — dla czystych implementacji JavaScript z nowoczesnymi audytami; tweetnacl — dla małego rozmiaru pakietu z prymitywami zgodnymi z NaCl; crypto-js — dla kompatybilności wstecznej (unikaj w nowym kodzie); natywne Web Crypto API — dla wszystkiego, co obsługuje. Ten przewodnik porównuje je pod kątem pokrycia algorytmów, rozmiaru pakietu, historii audytów, kompatybilności przeglądarka-Node oraz rzeczywistej wydajności przy szyfrowaniu pliku. Właściwy wybór zależy od tego, czy budujesz dla przeglądarek, Node, potrzebujesz ChaCha20-Poly1305 lub Argon2, czy możesz zmieścić się w granicach Web Crypto.
Tabela porównawcza
| Biblioteka | Rozmiar (skompresowany) | Backend | Kluczowe algorytmy | Audytowana | Aktualna? | |---|---|---|---|---|---| | Web Crypto API | 0 KB (natywna) | Natywna przeglądarka | AES-GCM, PBKDF2, RSA, ECDH, HMAC | Tak (przez producentów przeglądarek) | Tak, ale brak ChaCha/Argon2 | | libsodium.js | 200 KB WASM / 400 KB JS | WASM + fallback JS | Wszystko z libsodium | Tak (wielokrotnie) | Tak | | @noble/ciphers | 8 KB | Czysty JS | AES, ChaCha20, Poly1305, GCM-SIV | Tak (Cure53 2023) | Tak | | @noble/curves | 35 KB | Czysty JS | Ed25519, X25519, secp256k1, BLS | Tak (Trail of Bits, Cure53) | Tak | | tweetnacl | 15 KB | Czysty JS | Curve25519, Ed25519, XSalsa20-Poly1305 | Tak (oryginalny audyt NaCl) | Głównie tak, brak ChaCha20 | | crypto-js | 50 KB | Czysty JS | AES-CBC, SHA, HMAC, PBKDF2 | Brak aktualnego audytu | Nie, porzucona od 2023 | | node:crypto | 0 KB (natywna Node) | Natywna Node (OpenSSL) | Kompleksowe | Tak (OpenSSL) | Tak |
libsodium.js: szwajcarski scyzoryk
libsodium.js (kompilacja Emscripten biblioteki libsodium) to domyślny wybór gdy Web Crypto nie wystarcza. Obejmuje XChaCha20-Poly1305, Ed25519, X25519, Argon2id, BLAKE2b i API crypto_secretstream do strumieniowego AEAD. Kompilacja WASM działa z prędkością ok. 50–70% natywnego libsodium na typowym sprzęcie.
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
);
Strumieniowe API to kluczowa cecha przy transferze dużych plików. Możesz zaszyfrować plik 5 GB fragment po fragmencie bez ładowania całości do pamięci, a każdy fragment niesie własny tag uwierzytelniający, więc uszkodzenie jest wykrywane na poziomie fragmentu, a nie tylko na końcu.
Kompromisy: 200 KB WASM to dużo do wysłania. Stosuj dynamiczne importy (await import('libsodium-wrappers')), by biblioteka ładowała się tylko gdy szyfrowanie jest faktycznie potrzebne. Wersja sumo (zawiera wszystkie algorytmy) ma ponad 600 KB; używaj domyślnej kompilacji, chyba że potrzebujesz ekstra algorytmów.
@noble: mała, audytowana, nowoczesna
Rodzina @noble Paula Millera (@noble/ciphers, @noble/curves, @noble/hashes) to aktualnie najlepsza w klasie kryptografia JavaScript. Audytowana przez Cure53 (ciphers, 2023) i Trail of Bits (curves, 2022), zero zależności, tree-shakeable, natywny 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 nie używa WASM, więc wpływ na rozmiar pakietu jest mały (8 KB dla ciphers). Wydajność jest o 30–50% wolniejsza niż WASM libsodium dla masowego AES-GCM, ale wystarczająca dla większości scenariuszy transferu. Czysto-JS podejście oznacza też identyczne działanie w przeglądarkach, Node, Deno, Bun i React Native bez problemów z natywnymi modułami.
Używaj @noble gdy rozmiar pakietu ma znaczenie, gdy chcesz tree-shakeable biblioteki czystego JS, lub gdy jesteś na platformie, gdzie WASM ma problemy.
tweetnacl: minimalistyczna opcja
tweetnacl-js portuje bibliotekę C TweetNaCl Daniela J. Bernsteina do JavaScript. 15 KB po skompresowaniu. Obejmuje wymianę kluczy Curve25519, podpisy Ed25519 i uwierzytelnione szyfrowanie XSalsa20-Poly1305. Audytowana jako część oryginalnego projektu NaCl, choć nie niedawno.
import nacl from 'tweetnacl';
const key = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);
const ciphertext = nacl.secretbox(plaintext, nonce, key);
API jest celowo minimalistyczne: jeśli potrzebujesz więcej niż NaCl oferuje (np. AES-GCM dla interoperacyjności z systemami non-JS), szukaj gdzie indziej. Dla czystych aplikacji protokołu NaCl tweetnacl to nadal rozsądny wybór, choć @noble/ciphers plus @noble/curves pokrywa ten sam obszar z bardziej aktualnym utrzymaniem.
crypto-js: nie używaj do nowego kodu
crypto-js dominował w kryptografii przeglądarek w 2015 roku. W 2026 roku to zobowiązanie. Ostatnie znaczące wydanie to 2021 (4.1.1); repozytorium było praktycznie zarchiwizowane od 2023 roku. Domyślnie używa AES-CBC z niepewnym wyprowadzaniem kluczy z haseł (schemat w stylu EVP_BytesToKey OpenSSL), który wyprowadza klucze przez kilka rund MD5. CVE-2023-46233 sygnalizowało słabe domyślne PBKDF2.
Jeśli utrzymujesz starszy kod używający crypto-js, migracja do @noble/ciphers lub Web Crypto jest prosta i warta wysiłku. Dla nowego kodu w 2026 roku — pomiń crypto-js całkowicie.
node:crypto do kodu serwerowego
Wbudowany moduł crypto Node opakowuje OpenSSL i ma najszersze pokrycie algorytmów spośród wszystkich opcji na tej liście. Na Node 18+, require('crypto').webcrypto udostępnia API kompatybilne z Web Crypto, więc kod izomorficzny działa zarówno na serwerze, jak i kliencie.
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();
To najczystsza ścieżka do serwerowego deszyfrowania plików zaszyfrowanych przez Web Crypto. Jeśli Twoja usługa transferu pliku odszyfrowuje cokolwiek po stronie serwera (rzadkie w projektach zero-knowledge, ale częste w starszych systemach migrujących do szyfrowania), użyj node:crypto.
Wydajność przy rzeczywistym szyfrowaniu pliku
Benchmarki na MacBook Air M2 szyfrującym bufor 100 MB z AES-256-GCM:
- Web Crypto API (Chrome 120): 340 ms (akceleracja sprzętowa)
- Web Crypto API (Safari 17): 280 ms (akceleracja sprzętowa na Apple Silicon)
- libsodium.js WASM: 420 ms
- @noble/ciphers: 1850 ms (brak akceleracji sprzętowej w czystym JS)
- tweetnacl (XSalsa20): 1200 ms
- node:crypto: 180 ms (natywny OpenSSL)
Wniosek: Web Crypto wygrywa dla dużych plików, bo używa AES-NI. Czysty JS jest odpowiedni dla małych ładunków, ale dodaje sekundy przy transferach wielogigabajtowych. Dla przesyłania 5 GB różnica między Web Crypto a @noble/ciphers może wynosić 2 minuty kontra 10 minut czasu szyfrowania.
Hashowanie haseł: Argon2 lub nic
PBKDF2 to minimum, ale Argon2id jest lepszy. Opcje:
- argon2-browser: skompilowana referencja Argon2 WASM, 200 KB
- @noble/hashes: czysty JS Argon2id, 15 KB, wolniejszy ale czysty
- libsodium.js: Argon2id przez
crypto_pwhash, 200 KB, ale i tak masz libsodium jeśli go używasz
Używaj Argon2id z co najmniej 3 iteracjami, 64 MiB pamięci i 4 równoległości dla kluczy szyfrowania wyprowadzanych z hasła w przeglądarkach (wytyczne OWASP 2024).
Wybór dla Twojego stosu
- Budujesz prosty transfer pliku z szyfrowaniem AES-GCM: używaj Web Crypto bezpośrednio, bez biblioteki. HexaTransfer stosuje ten wzorzec.
- Potrzebujesz ChaCha20-Poly1305 lub strumieniowego AEAD: libsodium.js.
- Obawiasz się WASM lub wysyłasz do ograniczonych bundlerów: @noble/ciphers + @noble/curves.
- Używasz kluczy protokołu NaCl (np. sealed boxes do odbioru zaszyfrowanych plików): @noble lub libsodium, nie crypto-js.
- Migrujesz z crypto-js: przejdź na @noble jeśli rozmiar pakietu ma znaczenie, w przeciwnym razie na libsodium.js.
- Potrzebujesz podpisów post-kwantowych lub KEM: brak jeszcze dojrzałej biblioteki JS; sprawdź @noble/post-quantum (pre-release na początku 2026).
Sygnały audytu i utrzymania
Przed przyjęciem biblioteki kryptograficznej sprawdź:
- Datę ostatniego commitu (cokolwiek starszego niż 18 miesięcy to ryzyko)
- Publiczne raporty z audytów (Cure53, Trail of Bits, NCC Group)
- Tracker problemów dla nierozwiązanych kwestii bezpieczeństwa
- Liczbę zależności (mniej = mniejsza powierzchnia ataku)
- Tygodniowe pobrania npm (więcej = więcej oczu na kod)
Ekosystem JavaScript miał incydenty związane z łańcuchem dostaw (event-stream, ua-parser-js, colors), które czynią minimalne zależności właściwością bezpieczeństwa. Biblioteki kryptograficzne z zerowymi zależnościami runtime (@noble family, tweetnacl) są łatwiejsze do audytu od końca do końca niż te wciągające polyfille i narzędzia.
Wypróbuj na hexatransfer.com — bezpłatnie, bez konta, do 10 GB.
Wysyłaj duże pliki bezpiecznie z szyfrowaniem end-to-end
Przesyłaj pliki do 10 GB za darmo z szyfrowaniem end-to-end. Bez rejestracji. Twoje pliki są szyfrowane w przeglądarce przed przesłaniem — nikt inny nie może ich odczytać.
Wyślij plik