JavaScript暗号化ライブラリ:開発者向けトップピック
Web向け最良のJS暗号化ライブラリを比較。tweetnacl〜libsodium.jsからファイル転送プロジェクトに最適なライブラリを選択。
2026年のファイル転送に最適な JavaScript 暗号化ライブラリは、広範なカバレッジと WASM スピードには libsodium.js、最新の監査付き純粋 JS 実装には @noble/ciphers と @noble/curves、小さなバンドルサイズで NaCl 互換プリミティブには tweetnacl、レガシー互換性(新しいコードには使わないこと)には crypto-js、Web Crypto API がサポートするものには直接ネイティブ Web Crypto API です。このガイドではアルゴリズムカバレッジ・バンドルサイズ・監査履歴・ブラウザと Node の互換性・ファイル暗号化ワークロードでの実際のパフォーマンスで比較します。適切な選択は、ブラウザに出荷するか Node でビルドするか、ChaCha20-Poly1305 や Argon2 が必要か、Web Crypto の範囲内で生活できるかによって異なります。
比較表
| ライブラリ | サイズ(gzip後) | バックエンド | 主要アルゴリズム | 監査済み | モダンか | |---|---|---|---|---|---| | Web Crypto API | 0 KB(ネイティブ) | ブラウザネイティブ | AES-GCM・PBKDF2・RSA・ECDH・HMAC | あり(ブラウザベンダーによる) | あり(ただし ChaCha/Argon2 なし) | | libsodium.js | 200 KB WASM / 400 KB JS | WASM + JS フォールバック | libsodium のすべて | あり(複数) | あり | | @noble/ciphers | 8 KB | 純粋 JS | AES・ChaCha20・Poly1305・GCM-SIV | あり(Cure53 2023年) | あり | | @noble/curves | 35 KB | 純粋 JS | Ed25519・X25519・secp256k1・BLS | あり(Trail of Bits・Cure53) | あり | | tweetnacl | 15 KB | 純粋 JS | Curve25519・Ed25519・XSalsa20-Poly1305 | あり(元の NaCl 監査) | おおむね(ChaCha20 なし) | | crypto-js | 50 KB | 純粋 JS | AES-CBC・SHA・HMAC・PBKDF2 | 現行の監査なし | いいえ、2023年以降保守停止 | | node:crypto | 0 KB(Node ネイティブ) | Node ネイティブ(OpenSSL) | 包括的 | あり(OpenSSL) | あり |
libsodium.js:スイスアーミーナイフ
libsodium.js(libsodium の Emscripten コンパイルビルド)は Web Crypto では不十分な場合のデフォルトの選択です。XChaCha20-Poly1305・Ed25519・X25519・Argon2id・BLAKE2b・ストリーミング AEAD のための crypto_secretstream API をカバーします。WASM ビルドは典型的なハードウェアでネイティブ libsodium スピードの約50〜70%で動作します。
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
);
ストリーミング API は大きなファイル転送のキラー機能です。5 GB のファイルをすべてメモリに読み込まずにチャンクごとに暗号化でき、各チャンクが独自の認証タグを持つので破損がエンドだけでなくチャンクごとに検出されます。
トレードオフ:200 KB の WASM は多くを配信します。動的インポート(await import('libsodium-wrappers'))を使用して、ライブラリが実際に暗号化が必要な場合にのみロードされるようにしてください。sumo ビルド(すべてのアルゴリズムを含む)は600 KB 以上です。追加のものが必要でなければデフォルトビルドを使用してください。
@noble:小さく・監査済み・モダン
Paul Miller の @noble ファミリー(@noble/ciphers・@noble/curves・@noble/hashes)は現在の純粋 JavaScript 暗号のベストインクラスです。Cure53(ciphers、2023年)と Trail of Bits(curves、2022年)による監査済み、依存関係ゼロ、ツリーシェイカブル、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 は WASM を使用しないため、バンドルへの影響は小さいです(ciphers は8 KB)。パフォーマンスはバルク AES-GCM で libsodium の WASM より30〜50%遅いですが、ほとんどの転送シナリオで十分です。純粋 JS のアプローチは、ブラウザ・Node・Deno・Bun・React Native でネイティブモジュールの問題なく同一に動作することも意味します。
バンドルサイズが重要な場合、WASM に難がある場合、またはツリーシェイカブルな純粋 JS ライブラリが必要な場合に @noble を使用してください。
tweetnacl:ミニマリストの選択
tweetnacl-js は Daniel J. Bernstein の TweetNaCl C ライブラリを JavaScript にポートします。gzip 後15 KB。Curve25519 鍵交換・Ed25519 署名・XSalsa20-Poly1305 認証暗号化をカバーします。元の NaCl の取り組みの一部として監査されていますが、最近はされていません。
import nacl from 'tweetnacl';
const key = nacl.randomBytes(32);
const nonce = nacl.randomBytes(24);
const ciphertext = nacl.secretbox(plaintext, nonce, key);
API は意図的に小さいです。NaCl が提供するもの以上が必要な場合(例:非 JS システムとの相互運用のための AES-GCM)、他を見てください。純粋な NaCl プロトコルアプリには tweetnacl はまだ合理的な選択です。ただし @noble/ciphers と @noble/curves は同じ基盤を現在のメンテナンスでカバーしています。
crypto-js:新しいコードには使わない
crypto-js は2015年のブラウザ暗号の定番でした。2026年には負債です。最後の意味のあるリリースは2021年(4.1.1)で、リポジトリは2023年に事実上アーカイブされました。デフォルトで AES-CBC を使い、パスワードからの安全でない鍵導出(OpenSSL の EVP_BytesToKey スタイルのスキームで、MD5 の数ラウンドで鍵を導出)を採用しています。CVE-2023-46233 は弱い PBKDF2 デフォルトを指摘しました。
crypto-js を使用するレガシーコードを保守している場合、@noble/ciphers または Web Crypto への移行は直接的で価値があります。2026年に新しく始める場合は crypto-js を完全にスキップしてください。
サーバーコードのための node:crypto
Node の組み込み crypto モジュールは OpenSSL をラップし、このリストの中で最も広いアルゴリズムカバレッジを持ちます。Node 18+ では require('crypto').webcrypto が Web Crypto 互換 API を公開するため、アイソモーフィックなコードがサーバーとクライアントで動作します。
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();
Web Crypto で暗号化されたファイルのサーバーサイド復号にはこれが最もクリーンなパスです。ファイル転送サービスがサーバーサイドで何かを復号する場合(ゼロ知識設計では稀ですが、暗号化に移行するレガシーシステムでは一般的)、node:crypto を使用してください。
実際のファイル暗号化のパフォーマンス
MacBook Air M2 で100 MB バッファを AES-256-GCM で暗号化したベンチマーク:
- Web Crypto API(Chrome 120):340 ms(ハードウェアアクセラレーション)
- Web Crypto API(Safari 17):280 ms(Apple Silicon でハードウェアアクセラレーション)
- libsodium.js WASM:420 ms
- @noble/ciphers:1,850 ms(純粋 JS でハードウェアアクセラレーションなし)
- tweetnacl(XSalsa20):1,200 ms
- node:crypto:180 ms(ネイティブ OpenSSL)
結論:Web Crypto は AES-NI を使用するため大きなファイルで勝ります。純粋 JS は小さなペイロードでは問題ありませんが、マルチギガバイトの転送では数秒が追加されます。5 GB のアップロードでは、Web Crypto と @noble/ciphers の違いが2分対10分の暗号化時間になることがあります。
パスワードハッシング:Argon2 or Bust
PBKDF2 は最低限のテーブルステークスですが Argon2id の方が優れています。オプション:
- argon2-browser:WASM コンパイルされたリファレンス実装、200 KB
- @noble/hashes:純粋 JS の Argon2id、15 KB、遅いが純粋
- libsodium.js:
crypto_pwhash経由の Argon2id、200 KB(ただしすでに libsodium を使っているなら既に持っている)
ブラウザコンテキストのパスワード導出暗号化鍵には、少なくとも3回のイテレーション・64 MiB のメモリ・4の並列性で Argon2id を使用してください(OWASP 2024年ガイダンス)。
スタック別の選択
- AES-GCM 暗号化付きのシンプルなファイル転送を構築している: Web Crypto を直接使用し、ライブラリは不要。 HexaTransfer はこのパターンに従います。
- ChaCha20-Poly1305 またはストリーミング AEAD が必要: libsodium.js。
- WASM について心配があるか、制限されたバンドラーに出荷する: @noble/ciphers + @noble/curves。
- NaCl プロトコル鍵を使用している(例:暗号化ファイルの受信のためのシールドボックス): crypto-js ではなく @noble または libsodium。
- crypto-js から移行中: バンドルサイズが重要なら @noble、そうでなければ libsodium.js。
- 耐量子署名または KEM が必要: まだ成熟した JS ライブラリはありません。@noble/post-quantum(2026年初頭時点でプレリリース)を確認してください。
監査とメンテナンスのシグナル
暗号化ライブラリを採用する前に確認してください:
- 最後のコミット日(18か月以上古いものはリスクがある)
- 公開監査レポート(Cure53・Trail of Bits・NCC Group)
- 未解決のセキュリティ問題のイシュートラッカー
- 依存関係の数(少ないほど攻撃面が小さい)
- npm の週次ダウンロード数(多いほどコードに多くの目が向けられている)
JavaScript エコシステムはサプライチェーンインシデント(event-stream・ua-parser-js・colors)があり、最小限の依存関係はセキュリティ特性になっています。ランタイム依存関係がゼロの暗号ライブラリ(@noble ファミリー・tweetnacl)は、ポリフィルやユーティリティを引き込むものより端から端まで監査しやすいです。
hexatransfer.comでお試しください — 無料、登録不要、最大10GB。
エンドツーエンド暗号化で大容量ファイルを安全に送信
エンドツーエンド暗号化で最大10GBのファイルを無料で転送。アカウント不要。ファイルはアップロード前にブラウザで暗号化されるため、他の誰にも読まれません。
ファイルを送信