jose vs jsonwebtoken vs crypto-js vs jws vs node-jose
JWTおよび暗号化ライブラリの技術的比較
josejsonwebtokencrypto-jsjwsnode-jose類似パッケージ:

JWTおよび暗号化ライブラリの技術的比較

crypto-jsjosejsonwebtokenjwsnode-joseはいずれもJavaScript環境での暗号化やJWT(JSON Web Token)操作を目的としたnpmパッケージですが、それぞれ対応範囲や設計思想が大きく異なります。crypto-jsはAESやSHAなどの汎用暗号化アルゴリズムを提供し、JWTの操作はできません。joseはIETF標準に準拠したJWS/JWT/JWEのフルサポートを実現し、ブラウザとNode.jsの両方で動作します。jsonwebtokenはNode.js向けのJWT署名・検証に特化したシンプルなライブラリです。jwsはJWTの署名部分(JWS)のみを扱う低レベルなライブラリです。node-joseはかつてJWE/JWSをサポートしていましたが、現在は公式に非推奨(deprecated)となっており、新規プロジェクトでの使用は推奨されません。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
jose103,499,5737,716257 kB17日前MIT
jsonwebtoken53,323,96618,17943.4 kB2058ヶ月前MIT
crypto-js18,951,03916,393487 kB2783年前MIT
jws072218.8 kB338ヶ月前MIT
node-jose0721353 kB733年前Apache-2.0

JWTおよび暗号化ライブラリの比較:crypto-js、jose、jsonwebtoken、jws、node-jose

フロントエンド開発において、トークンの生成・検証やデータの暗号化はセキュリティの要です。しかし、crypto-jsjosejsonwebtokenjwsnode-joseといったnpmパッケージはそれぞれ設計思想や用途が異なり、適切な選択を誤ると実装の複雑さや脆弱性につながります。ここでは、これらのライブラリを実際のコード例を交えて深く比較し、現場でどう使い分けるべきかを解説します。

🔐 ライブラリの目的と対応範囲

まず、各ライブラリが何を得意としているかを整理しましょう。

  • crypto-js:汎用的な暗号化ライブラリ。AES、SHA-256、HMACなど幅広いアルゴリズムをサポート。JWTの操作はできません。
  • jose:IETF標準(RFC 7515〜7519)に準拠したJWS/JWT/JWEのフルサポート。現代的なWeb Crypto API互換。
  • jsonwebtoken:Node.js向けのJWT署名・検証に特化。シンプルで使いやすいが、JWE(暗号化JWT)非対応。
  • jws:JWTの署名部分(JWS)のみを扱う低レベルライブラリ。jsonwebtokenの内部で使われることも。
  • node-jose:古くからあるJWE/JWS実装だが、公式に非推奨(deprecated)。新規プロジェクトでの使用は避けるべき。

💡 注:node-joseはnpmページおよびGitHubリポジトリで「This library is deprecated.」と明記されており、メンテナンスも停止されています。代わりにjoseの使用が推奨されています。

🧪 署名付きJWTの生成と検証

最も一般的なユースケースである「署名付きJWT(JWS)の作成・検証」を各ライブラリで実装してみましょう。

jose(推奨)

joseはTypeScript対応で、Web Crypto API互換のためブラウザ・Node.js両方で動作します。

// JWTの署名(HS256)
import { SignJWT } from 'jose';

const secret = new TextEncoder().encode('your-secret');
const jwt = await new SignJWT({ userId: 123 })
  .setProtectedHeader({ alg: 'HS256' })
  .setIssuedAt()
  .setExpirationTime('1h')
  .sign(secret);

// JWTの検証
import { jwtVerify } from 'jose';

const { payload } = await jwtVerify(jwt, secret);
console.log(payload.userId); // 123

jsonwebtoken

Node.js環境で広く使われてきましたが、ブラウザでは動作しません(Node固有のcryptoモジュール依存)。

// JWTの署名
import jwt from 'jsonwebtoken';

const token = jwt.sign({ userId: 123 }, 'your-secret', { expiresIn: '1h' });

// JWTの検証
const decoded = jwt.verify(token, 'your-secret');
console.log(decoded.userId); // 123

jws

低レベルな操作が必要な場合に使われますが、高レベルなJWT機能(有効期限チェックなど)は含まれません。

// JWSの署名(JWTではない)
import jws from 'jws';

const signature = jws.sign({
  header: { alg: 'HS256' },
  payload: JSON.stringify({ userId: 123 }),
  secret: 'your-secret'
});

// 検証
const isValid = jws.verify(signature, 'HS256', 'your-secret');

crypto-jsnode-jose

  • crypto-jsはJWTを扱えません。ハッシュや暗号化には使えますが、JWTの構造(ヘッダー・ペイロード・署名のBase64Urlエンコード)を自前で実装する必要があります。
  • node-joseは非推奨のため、コード例は省略します。

🔒 暗号化JWT(JWE)のサポート

機密情報を含むJWTを暗号化したい場合、JWE対応が必要です。

  • jose:完全対応。RSA-OAEP、AES-GCMなどのアルゴリズムをサポート。
// JWEの暗号化
import { EncryptJWT, importJWK } from 'jose';

const publicKey = await importJWK({ kty: 'RSA', ... }, 'RSA-OAEP');
const jwe = await new EncryptJWT({ ssn: '123-45-6789' })
  .setProtectedHeader({ alg: 'RSA-OAEP', enc: 'A256GCM' })
  .encrypt(publicKey);

// 復号
import { jwtDecrypt } from 'jose';
const privateKey = await importJWK({ kty: 'RSA', ... }, 'RSA-OAEP');
const { payload } = await jwtDecrypt(jwe, privateKey);
  • jsonwebtokenjwscrypto-js:JWE非対応。
  • node-jose:JWE対応していましたが、非推奨のため使用不可。

🌐 ブラウザ vs Node.js の互換性

ライブラリブラウザNode.js
jose
jsonwebtoken
jws⚠️(制限あり)
crypto-js
node-jose❌(非推奨)❌(非推奨)

jsonwebtokenはNode.jsのcryptoモジュールに依存しているため、ブラウザでは動作しません。一方、joseはWeb Crypto APIを使用するため、モダンブラウザでそのまま使えます。

🛠 実装の手間と安全性

  • jose:API設計が洗練されており、タイムスタンプの自動処理(nbfexp)、署名アルゴリズムの厳格な検証など、セキュリティベストプラクティスが組み込まれています。
  • jsonwebtoken:簡単ですが、{ algorithms: [...] }オプションを指定しないと脆弱性(署名なしのnoneアルゴリズム許容)が発生する可能性があります。
  • jws:低レベルすぎるため、開発者がJWTの仕様を正確に理解していないとバグや脆弱性を生みやすいです。
  • crypto-js:JWTの構造を自前で実装すると、Base64Urlエンコードのミスや署名検証漏れが起きやすいです。

📌 まとめ:どのライブラリを選ぶべきか?

  • 新規プロジェクトでJWTを使うなら → jose

    • ブラウザ・Node.js両対応
    • JWS/JWE完全サポート
    • セキュリティ面で堅牢
  • Node.js専用でシンプルなJWT署名が必要 → jsonwebtoken

    • ただし、ブラウザ非対応
    • JWE不要なら十分使える
  • 低レベルなJWS操作が必要 → jws

    • 高度なカスタマイズが必要な場合のみ
  • 汎用暗号化(JWT以外)→ crypto-js

    • AES、SHA、HMACなど
    • JWTの操作には不向き
  • node-jose → 使用禁止

    • 非推奨のため、新規プロジェクトでは絶対に使わないでください

💡 最終アドバイス

フロントエンド開発者がJWTを扱う場合、秘密鍵や署名キーをクライアント側に置かないことが大前提です。JWTの検証はサーバー側で行い、クライアントはトークンを安全に保管(HttpOnly Cookieなど)する役割に徹すべきです。その上で、クライアントでJWEの復号が必要な特殊ケースを除き、ほとんどの場合joseが最適解となります。

選び方: jose vs jsonwebtoken vs crypto-js vs jws vs node-jose

  • jose:

    joseは現代的なJWT操作(JWS署名・検証、JWE暗号化・復号)を必要とするプロジェクトに最適です。IETF標準に完全準拠しており、ブラウザとNode.jsの両方で動作します。TypeScript対応で、セキュリティベストプラクティス(例:アルゴリズムの厳格な検証、タイムスタンプ自動処理)が組み込まれているため、新規プロジェクトでは第一候補として検討すべきです。

  • jsonwebtoken:

    jsonwebtokenはNode.js環境でシンプルなJWT署名・検証が必要な場合に適しています。ブラウザでは動作しないため、フロントエンド専用のプロジェクトには使えません。JWE(暗号化JWT)のサポートはありませんが、基本的な認証フロー(例:アクセストークンの発行)には十分です。ただし、algorithmsオプションを明示的に指定しないと脆弱性が発生する可能性がある点に注意してください。

  • crypto-js:

    crypto-jsはJWTではなく、AES、SHA-256、HMACなどの汎用的な暗号化やハッシュ処理が必要な場合に選んでください。JWTの生成や検証には対応していないため、トークン操作には不向きです。ブラウザとNode.jsの両方で動作しますが、セキュリティ的に敏感な操作(例:秘密鍵の管理)はクライアント側で行わないよう注意が必要です。

  • jws:

    jwsはJWTの署名部分(JWS)を低レベルで操作したい場合に選んでください。高レベルなJWT機能(例:有効期限の自動検証)は含まれないため、開発者が仕様を正確に理解していないとバグや脆弱性を生みやすいです。通常はjsonwebtokenの内部実装として使われることが多く、直接使うケースは限定的です。

  • node-jose:

    node-joseは公式に非推奨(deprecated)となっており、新規プロジェクトでの使用は絶対に避けてください。代わりにjoseパッケージの使用が強く推奨されています。既存プロジェクトで使っている場合は、早急に移行を検討すべきです。

jose のREADME

jose

jose is a JavaScript module for JSON Object Signing and Encryption, providing support for JSON Web Tokens (JWT), JSON Web Signature (JWS), JSON Web Encryption (JWE), JSON Web Key (JWK), JSON Web Key Set (JWKS), and more. The module is designed to work across various Web-interoperable runtimes including Node.js, browsers, Cloudflare Workers, Deno, Bun, and others.

Sponsor

Auth0 by Okta

If you want to quickly add JWT authentication to JavaScript apps, feel free to check out Auth0's JavaScript SDK and free plan. Create an Auth0 account; it's free!

💗 Help the project

Support from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by becoming a sponsor.

Dependencies: 0

jose has no dependencies and it exports tree-shakeable ESM1.

Documentation

jose is distributed via npmjs.com, jsr.io, jsdelivr.com, and github.com.

example ESM import1

import * as jose from 'jose'

JSON Web Tokens (JWT)

The jose module supports JSON Web Tokens (JWT) and provides functionality for signing and verifying tokens, as well as their JWT Claims Set validation.

Encrypted JSON Web Tokens

The jose module supports encrypted JSON Web Tokens and provides functionality for encrypting and decrypting tokens, as well as their JWT Claims Set validation.

Key Utilities

The jose module supports importing, exporting, and generating keys and secrets in various formats, including PEM formats like SPKI, X.509 certificate, and PKCS #8, as well as JSON Web Key (JWK).

JSON Web Signature (JWS)

The jose module supports signing and verification of JWS messages with arbitrary payloads in Compact, Flattened JSON, and General JSON serialization syntaxes.

JSON Web Encryption (JWE)

The jose module supports encryption and decryption of JWE messages with arbitrary plaintext in Compact, Flattened JSON, and General JSON serialization syntaxes.

Other

The following are additional features and utilities provided by the jose module:

Supported Runtimes

The jose module is compatible with JavaScript runtimes that support the utilized Web API globals and standard built-in objects or are Node.js.

The following runtimes are supported (this is not an exhaustive list):

Please note that certain algorithms may not be available depending on the runtime used. You can find a list of available algorithms for each runtime in the specific issue links provided above.

Supported Versions

VersionSecurity Fixes 🔑Other Bug Fixes 🐞New Features ⭐Runtime and Module type
v6.xSecurity PolicyUniversal2 ESM1

Specifications

Details
  • JSON Web Signature (JWS) - RFC7515
  • JSON Web Encryption (JWE) - RFC7516
  • JSON Web Key (JWK) - RFC7517
  • JSON Web Algorithms (JWA) - RFC7518
  • JSON Web Token (JWT) - RFC7519
  • JSON Web Key Thumbprint - RFC7638
  • JSON Web Key Thumbprint URI - RFC9278
  • JWS Unencoded Payload Option - RFC7797
  • CFRG Elliptic Curve ECDH and Signatures - RFC8037
  • Fully-Specified Algorithms for JOSE - RFC9864
  • ML-DSA for JOSE - RFC9964

The algorithm implementations in jose have been tested using test vectors from their respective specifications as well as RFC7520.

Footnotes

  1. CJS style let jose = require('jose') is possible in Node.js versions where the require(esm) feature is enabled by default (^20.19.0 || ^22.12.0 || >= 23.0.0). 2 3

  2. Assumes runtime support of WebCryptoAPI and Fetch API