Przejdź do treści
HexaTransfer
Wróć do bloga
Szyfrowanie i bezpieczenstwo

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