Bibliotecas de encriptação JavaScript: melhores escolhas para programadores
Compare as melhores bibliotecas de encriptação JS para aplicações web. De tweetnacl a libsodium.js, encontre a certa para o seu projeto de transferência de ficheiros.
As melhores bibliotecas de encriptação JavaScript para trabalho de transferência de ficheiros em 2026 são: libsodium.js para cobertura ampla e velocidade WASM, @noble/ciphers e @noble/curves para implementações JavaScript puro com auditorias modernas, tweetnacl para tamanho de bundle reduzido com primitivos compatíveis com NaCl, crypto-js para compatibilidade legada (evitar em código novo) e a Web Crypto API nativa para tudo o que suporte. Este guia compara-as em cobertura de algoritmos, tamanho de bundle, historial de auditorias, compatibilidade browser vs Node e desempenho real em cargas de trabalho de encriptação de ficheiros. A escolha certa depende de estar a distribuir para browsers, a construir em Node, a precisar de ChaCha20-Poly1305 ou Argon2, ou de conseguir trabalhar dentro dos limites da Web Crypto.
Tabela de comparação
| Biblioteca | Tamanho (gzipped) | Backend | Algoritmos principais | Auditada | Moderna? | |---|---|---|---|---|---| | Web Crypto API | 0 KB (nativa) | Nativa do browser | AES-GCM, PBKDF2, RSA, ECDH, HMAC | Sim (pelos fornecedores dos browsers) | Sim, mas sem ChaCha/Argon2 | | libsodium.js | 200 KB WASM / 400 KB JS | WASM + fallback JS | Tudo em libsodium | Sim (múltiplas) | Sim | | @noble/ciphers | 8 KB | JS puro | AES, ChaCha20, Poly1305, GCM-SIV | Sim (Cure53 2023) | Sim | | @noble/curves | 35 KB | JS puro | Ed25519, X25519, secp256k1, BLS | Sim (Trail of Bits, Cure53) | Sim | | tweetnacl | 15 KB | JS puro | Curve25519, Ed25519, XSalsa20-Poly1305 | Sim (auditoria NaCl original) | Maioritariamente, sem ChaCha20 | | crypto-js | 50 KB | JS puro | AES-CBC, SHA, HMAC, PBKDF2 | Sem auditoria atual | Não, sem manutenção desde 2023 | | node:crypto | 0 KB (nativo do Node) | Node nativo (OpenSSL) | Abrangente | Sim (OpenSSL) | Sim |
libsodium.js: o canivete suíço
O libsodium.js (a compilação Emscripten do libsodium) é a escolha padrão quando a Web Crypto não é suficiente. Cobre XChaCha20-Poly1305, Ed25519, X25519, Argon2id, BLAKE2b e a API crypto_secretstream para AEAD em streaming. A compilação WASM corre a aproximadamente 50 a 70% da velocidade do libsodium nativo em hardware típico.
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
);
A API de streaming é a funcionalidade diferenciadora para transferências de ficheiros grandes. Pode encriptar um ficheiro de 5 GB fragmento a fragmento sem carregar tudo na memória, e cada fragmento tem a sua própria etiqueta de autenticação para que a corrupção seja detetada por fragmento, não apenas no final.
Contrapartidas: 200 KB de WASM é muito para distribuir. Use importações dinâmicas (await import('libsodium-wrappers')) para que a biblioteca só carregue quando a encriptação é realmente necessária. A compilação sumo (inclui todos os algoritmos) tem mais de 600 KB; use a compilação padrão a não ser que precise dos extras.
@noble: pequeno, auditado, moderno
A família @noble de Paul Miller (@noble/ciphers, @noble/curves, @noble/hashes) é atualmente a referência em JavaScript criptográfico puro. Auditado pela Cure53 (ciphers, 2023) e Trail of Bits (curves, 2022), zero dependências, tree-shakeable, nativo em 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);
O @noble não usa WASM, pelo que o impacto no bundle é pequeno (8 KB para ciphers). O desempenho é 30 a 50% mais lento do que o WASM do libsodium para AES-GCM em massa, mas suficiente para a maioria dos cenários de transferência. A abordagem de JS puro significa também que funciona de forma idêntica em browsers, Node, Deno, Bun e React Native sem problemas com módulos nativos.
Use @noble quando o tamanho do bundle importa, quando quer uma biblioteca JS puro tree-shakeable, ou quando está numa plataforma onde o WASM tem comportamentos irregulares.
tweetnacl: o minimalista
O tweetnacl-js é uma portagem da biblioteca TweetNaCl C de Daniel J. Bernstein para JavaScript. 15 KB comprimido. Cobre troca de chaves Curve25519, assinaturas Ed25519 e encriptação autenticada XSalsa20-Poly1305. Auditado como parte do esforço NaCl original, embora não recentemente.
import nacl from 'tweetnacl';
const key = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);
const ciphertext = nacl.secretbox(plaintext, nonce, key);
A API é deliberadamente minúscula: se precisar de mais do que o NaCl fornece (por exemplo, AES-GCM para interoperabilidade com sistemas não-JS), procure noutra parte. Para aplicações puras do protocolo NaCl, o tweetnacl é ainda uma escolha razoável, embora @noble/ciphers mais @noble/curves cubra o mesmo terreno com manutenção mais atual.
crypto-js: não usar em código novo
O crypto-js dominou a criptografia no browser em 2015. Em 2026 é uma responsabilidade. O último lançamento significativo foi 2021 (4.1.1); o repositório foi efetivamente arquivado em 2023. Por defeito usa AES-CBC com uma derivação de chave insegura a partir de palavras-passe (esquema ao estilo EVP_BytesToKey do OpenSSL), que deriva chaves via algumas rondas de MD5. A CVE-2023-46233 sinalizou predefinições PBKDF2 fracas.
Se estiver a manter código legado que usa crypto-js, a migração para @noble/ciphers ou Web Crypto é direta e vale o esforço. Se estiver a começar do zero em 2026, ignore o crypto-js completamente.
node:crypto para código de servidor
O módulo crypto incorporado no Node envolve o OpenSSL e tem a cobertura de algoritmos mais ampla de tudo nesta lista. No Node 18+, require('crypto').webcrypto expõe uma API compatível com Web Crypto, pelo que o código isomórfico funciona no servidor e no cliente.
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();
Para decifração do lado do servidor de ficheiros encriptados com Web Crypto, este é o caminho mais limpo. Se o seu serviço de transferência de ficheiros decifra algo do lado do servidor (raro em designs zero-knowledge, mas comum em sistemas legados a migrar para encriptação), use node:crypto.
Desempenho em encriptação real de ficheiros
Benchmarks num MacBook Air M2 a encriptar um buffer de 100 MB com AES-256-GCM:
- Web Crypto API (Chrome 120): 340 ms (com aceleração de hardware)
- Web Crypto API (Safari 17): 280 ms (com aceleração de hardware no Apple Silicon)
- libsodium.js WASM: 420 ms
- @noble/ciphers: 1 850 ms (sem aceleração de hardware em JS puro)
- tweetnacl (XSalsa20): 1 200 ms
- node:crypto: 180 ms (OpenSSL nativo)
Conclusão: a Web Crypto vence para ficheiros grandes porque usa AES-NI. O JS puro é adequado para payloads pequenos mas adiciona segundos em transferências de múltiplos gigabytes. Para um carregamento de 5 GB, a diferença entre Web Crypto e @noble/ciphers pode ser de 2 minutos versus 10 minutos de tempo de encriptação.
Hashing de palavras-passe: Argon2 ou equivalente
O PBKDF2 é o mínimo aceitável, mas o Argon2id é melhor. Opções:
- argon2-browser: implementação de referência compilada em WASM, 200 KB
- @noble/hashes: Argon2id em JS puro, 15 KB, mais lento mas puro
- libsodium.js: Argon2id via
crypto_pwhash, 200 KB mas já disponível se estiver a usar libsodium
Use Argon2id com pelo menos 3 iterações, 64 MiB de memória e 4 de paralelismo para chaves de encriptação derivadas de palavras-passe em contextos de browser (orientação OWASP 2024).
Escolher para a sua solução
- Está a construir uma transferência simples de ficheiros com encriptação AES-GCM: use Web Crypto diretamente, sem biblioteca. O HexaTransfer segue este padrão.
- Precisa de ChaCha20-Poly1305 ou AEAD em streaming: libsodium.js.
- Está preocupado com WASM ou distribui para bundlers restritos: @noble/ciphers + @noble/curves.
- Usa chaves de protocolo NaCl (por exemplo, caixas seladas para receção de ficheiros encriptados): @noble ou libsodium, não crypto-js.
- Está a migrar do crypto-js: mova para @noble se o tamanho do bundle importar, libsodium.js caso contrário.
- Precisa de assinaturas pós-quânticas ou KEM: sem biblioteca JS madura ainda; verifique @noble/post-quantum (pré-lançamento no início de 2026).
Sinais de auditoria e manutenção
Antes de adotar uma biblioteca criptográfica, verifique:
- Data do último commit (qualquer coisa acima de 18 meses sem atualização é arriscado)
- Relatórios de auditoria públicos (Cure53, Trail of Bits, NCC Group)
- Rastreador de problemas para questões de segurança não resolvidas
- Contagem de dependências (menos = superfície de ataque menor)
- Transferências semanais no npm (mais = mais olhos no código)
O ecossistema JavaScript teve incidentes na cadeia de fornecimento (event-stream, ua-parser-js, colors) que tornam as dependências mínimas uma propriedade de segurança. As bibliotecas criptográficas com zero dependências de tempo de execução (família @noble, tweetnacl) são mais fáceis de auditar de ponta a ponta do que aquelas que puxam polyfills e utilitários.
Experimente em hexatransfer.com — gratuito, sem conta, até 10 GB.
Envie arquivos grandes com segurança e criptografia de ponta a ponta
Transfira arquivos de até 10 GB gratuitamente com criptografia de ponta a ponta. Sem necessidade de conta. Seus arquivos são criptografados no navegador antes do envio — ninguém mais pode lê-los.
Enviar um arquivo