Librerie di crittografia JavaScript: le migliori scelte
Confronta le migliori librerie di crittografia JS per il web. Da tweetnacl a libsodium.js, trova quella giusta.
Le migliori librerie di crittografia JavaScript per il trasferimento file nel 2026 sono: libsodium.js per copertura algoritmica completa e velocità WASM, @noble/ciphers e @noble/curves per implementazioni pure-JS con audit recenti, tweetnacl per bundle ridotto con primitive NaCl-compatibili, crypto-js solo per compatibilità con codice legacy (da evitare per nuovi progetti), e la Web Crypto API nativa per tutto ciò che supporta. Questa guida le confronta su copertura algoritmica, dimensione del bundle, storico degli audit, compatibilità browser/Node e prestazioni reali con carichi di crittografia file. La scelta giusta dipende dal target — browser o Node — dalla necessità di ChaCha20-Poly1305 o Argon2, o dalla possibilità di restare entro i limiti di Web Crypto.
Tabella di confronto
| Libreria | Dimensione (gzip) | Backend | Algoritmi principali | Auditata | Moderna? | |---|---|---|---|---|---| | Web Crypto API | 0 KB (nativa) | Browser nativo | AES-GCM, PBKDF2, RSA, ECDH, HMAC | Sì (vendor browser) | Sì, ma no ChaCha/Argon2 | | libsodium.js | 200 KB WASM / 400 KB JS | WASM + JS fallback | Tutto libsodium | Sì (multipli) | Sì | | @noble/ciphers | 8 KB | Pure JS | AES, ChaCha20, Poly1305, GCM-SIV | Sì (Cure53 2023) | Sì | | @noble/curves | 35 KB | Pure JS | Ed25519, X25519, secp256k1, BLS | Sì (Trail of Bits, Cure53) | Sì | | tweetnacl | 15 KB | Pure JS | Curve25519, Ed25519, XSalsa20-Poly1305 | Sì (audit NaCl originale) | In gran parte, manca ChaCha20 | | crypto-js | 50 KB | Pure JS | AES-CBC, SHA, HMAC, PBKDF2 | Nessun audit aggiornato | No, abbandonata dal 2023 | | node:crypto | 0 KB (nativo Node) | Node nativo (OpenSSL) | Completo | Sì (OpenSSL) | Sì |
libsodium.js: il coltellino svizzero
libsodium.js (la build Emscripten di libsodium) è la scelta predefinita quando Web Crypto non è sufficiente. Copre XChaCha20-Poly1305, Ed25519, X25519, Argon2id, BLAKE2b e l'API crypto_secretstream per streaming AEAD. La build WASM gira a circa il 50–70% della velocità nativa di libsodium su hardware tipico.
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
);
L'API di streaming è la funzionalità principale per trasferimenti di file di grandi dimensioni. Puoi cifrare un file da 5 GB a blocchi senza caricarlo tutto in memoria: ogni blocco porta il proprio tag di autenticazione, così la corruzione viene rilevata blocco per blocco e non solo alla fine.
Compromessi: 200 KB di WASM sono un peso rilevante. Usa gli import dinamici (await import('libsodium-wrappers')) affinché la libreria venga caricata solo quando la crittografia è davvero necessaria. La build sumo (che include tutti gli algoritmi) supera i 600 KB; usa la build predefinita a meno che tu non abbia bisogno degli extra.
@noble: compatta, auditata e moderna
La famiglia @noble di Paul Miller (@noble/ciphers, @noble/curves, @noble/hashes) è attualmente il riferimento per la crittografia in pure JavaScript. Auditata da Cure53 (ciphers, 2023) e Trail of Bits (curves, 2022), zero dipendenze, tree-shakeable, TypeScript-native.
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 non usa WASM, quindi l'impatto sul bundle è ridotto (8 KB per ciphers). Le prestazioni sono del 30–50% inferiori a libsodium WASM per AES-GCM bulk, ma sufficienti per la maggior parte degli scenari di trasferimento. L'approccio pure-JS garantisce comportamento identico su browser, Node, Deno, Bun e React Native senza problemi con i moduli nativi.
Usa @noble quando la dimensione del bundle conta, quando vuoi una libreria pure-JS tree-shakeable, o su piattaforme in cui WASM ha qualche intoppo.
tweetnacl: l'approccio minimalista
tweetnacl-js porta la libreria C TweetNaCl di Daniel J. Bernstein in JavaScript. 15 KB compressa. Copre lo scambio di chiavi Curve25519, le firme Ed25519 e la cifratura autenticata XSalsa20-Poly1305. Auditata nell'ambito del progetto NaCl originale, ma non di recente.
import nacl from 'tweetnacl';
const key = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);
const ciphertext = nacl.secretbox(plaintext, nonce, key);
L'API è volutamente minima: se hai bisogno di più di quanto NaCl offre — ad esempio AES-GCM per interoperabilità con sistemi non-JS — guarda altrove. Per applicazioni che usano esclusivamente il protocollo NaCl, tweetnacl resta una scelta ragionevole, anche se @noble/ciphers più @noble/curves copre lo stesso terreno con manutenzione più aggiornata.
crypto-js: da non usare per nuovo codice
crypto-js ha dominato la crittografia browser nel 2015. Nel 2026 è un rischio. L'ultima release significativa risale al 2021 (4.1.1); il repository è stato di fatto archiviato nel 2023. Di default usa AES-CBC con una derivazione della chiave dalla password non sicura (schema EVP_BytesToKey di OpenSSL), che deriva le chiavi tramite pochi round di MD5. CVE-2023-46233 ha segnalato i default deboli di PBKDF2.
Se mantieni codice legacy che usa crypto-js, migrare a @noble/ciphers o Web Crypto è semplice e ne vale la pena. Se inizi da zero nel 2026, salta crypto-js completamente.
node:crypto per il codice server
Il modulo crypto integrato di Node avvolge OpenSSL e ha la copertura algoritmica più ampia dell'elenco. Da Node 18+, require('crypto').webcrypto espone un'API compatibile con Web Crypto, così il codice isomorfico funziona sia lato server che lato client.
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();
Per la decrittografia server-side di file cifrati con Web Crypto, questo è il percorso più pulito. Se il tuo servizio di trasferimento decifra qualcosa lato server — raro in architetture zero-knowledge, ma comune in sistemi legacy che migrano verso la crittografia — usa node:crypto.
Prestazioni reali sulla cifratura file
Benchmark su MacBook Air M2 per la cifratura di un buffer da 100 MB con AES-256-GCM:
- Web Crypto API (Chrome 120): 340 ms (accelerazione hardware)
- Web Crypto API (Safari 17): 280 ms (accelerazione hardware su Apple Silicon)
- libsodium.js WASM: 420 ms
- @noble/ciphers: 1.850 ms (nessuna accelerazione hardware in pure JS)
- tweetnacl (XSalsa20): 1.200 ms
- node:crypto: 180 ms (OpenSSL nativo)
La Web Crypto API vince per file di grandi dimensioni perché utilizza AES-NI. Il pure JS va bene per payload piccoli, ma aggiunge secondi su trasferimenti multi-gigabyte. Per un upload da 5 GB, la differenza tra Web Crypto e @noble/ciphers potrebbe essere 2 minuti contro 10 di solo tempo di cifratura.
Password hashing: Argon2 o niente
PBKDF2 è il minimo indispensabile, ma Argon2id è superiore. Opzioni disponibili:
- argon2-browser: implementazione di riferimento compilata in WASM, 200 KB
- @noble/hashes: Argon2id pure-JS, 15 KB, più lento ma senza dipendenze
- libsodium.js: Argon2id via
crypto_pwhash, 200 KB — già presente se usi libsodium
Usa Argon2id con almeno 3 iterazioni, 64 MiB di memoria e parallelismo 4 per le chiavi di cifratura derivate da password in contesti browser (guida OWASP 2024).
Scegliere in base allo stack
- Stai costruendo un semplice trasferimento file con AES-GCM: usa Web Crypto direttamente, senza librerie. HexaTransfer segue questo pattern.
- Hai bisogno di ChaCha20-Poly1305 o streaming AEAD: libsodium.js.
- Sei diffidente verso WASM o hai bundler con limitazioni: @noble/ciphers + @noble/curves.
- Usi chiavi NaCl-protocol (ad esempio sealed box per ricezione di file cifrati): @noble o libsodium, non crypto-js.
- Stai migrando da crypto-js: vai su @noble se la dimensione del bundle conta, altrimenti libsodium.js.
- Hai bisogno di firme post-quantum o KEM: nessuna libreria JS matura disponibile; controlla @noble/post-quantum (pre-release a inizio 2026).
Segnali di audit e manutenzione
Prima di adottare una libreria crittografica, verifica:
- Data dell'ultimo commit (qualsiasi cosa oltre 18 mesi senza aggiornamenti è rischiosa)
- Report di audit pubblici (Cure53, Trail of Bits, NCC Group)
- Issue tracker per problemi di sicurezza irrisolti
- Numero di dipendenze (meno = superficie di attacco ridotta)
- Download settimanali su npm (più alti = più occhi sul codice)
L'ecosistema JavaScript ha subito incidenti di supply chain (event-stream, ua-parser-js, colors) che rendono le dipendenze minime una vera proprietà di sicurezza. Le librerie crittografiche con zero dipendenze runtime (famiglia @noble, tweetnacl) sono più semplici da auditare end-to-end rispetto a quelle che portano con sé polyfill e utilità varie.
Provalo su hexatransfer.com — gratis, senza registrazione, fino a 10 GB.
Invia file di grandi dimensioni in modo sicuro con crittografia end-to-end
Trasferisci file fino a 10 GB gratuitamente con crittografia end-to-end. Nessun account necessario. I tuoi file vengono crittografati nel browser prima del caricamento — nessun altro può leggerli.
Invia un file