Ir para o conteúdo
HexaTransfer
Voltar ao blog
Criptografia e seguranca

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