JWTトークンの概要、署名アルゴリズム、セキュリティのベストプラクティス
Rudra Chauhan, Senior Systems Architect
JWTトークンの概要、署名アルゴリズム、セキュリティのベストプラクティス
JSON Web Tokens (JWT)は、RFC 7519で指定されたオープンで業界標準の方法で、2つのパーティー間で安全にクレームを表現するために使用されます。JWTは、REST API、マイクロサービス、シングルページアプリケーション (SPA)などでステートレス認証に広く使用されています。
ただし、JWTの検証を適切に実装しないと、認証のバイパス脆弱性を引き起こす可能性があります。
JWTトークンの構造
JWTトークンは、3つのbase64urlエンコードされた部分で構成されており、ドット (.) で区切られています。
ヘッダー . ペイロード . 署名
例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
1. ヘッダー
ヘッダーにはトークンのタイプと署名アルゴリズムが含まれます。
json{ "alg": "HS256", "typ": "JWT" }
2. ペイロード (クレーム)
ユーザーに関するステートメントと追加のメタデータが含まれます。
sub(Subject): ユーザーIDiat(Issued At): 時刻exp(Expiration): 有効期限iss(Issuer): IDプロバイダーURL
3. 署名
ヘッダー、ペイロード、秘密鍵を使用して署名アルゴリズムで署名されます。
JWTペイロードの構造
json{ "iss": "https://example.com", "sub": "1234567890", "iat": 1643723900, "exp": 1643723900, "aud": "https://example.com/api/v1", "jti": "1234567890", "name": "John Doe", "email": "john.doe@example.com", "roles": ["admin", "moderator"] }
JWT署名の生成
bashecho -n '{"alg":"HS256","typ":"JWT"}' | base64 echo -n '{"iss":"https://example.com","sub":"1234567890","iat":1643723900,"exp":1643723900,"aud":"https://example.com/api/v1","jti":"1234567890","name":"John Doe","email":"john.doe@example.com","roles":["admin","moderator"]}' | base64 secret_key="your_secret_key_here" signature=$(echo -n "$(base64 -d <<< "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9")$(base64 -d <<< "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ")" | openssl dgst -sha256 -hmac "$secret_key" -binary | base64 -w 0)
2. 同期 (HS256) vs 非同期 (RS256) 署名
| 特性 | HMAC SHA-256 (HS256) | RSA SHA-256 (RS256) |
|---|---|---|
| キー種類 | 共有シークレット (同期) | 公開鍵/秘密鍵ペア (非同期) |
| 署名 | シークレットキーを使用して行う | 秘密鍵を使用して行う |
| 検証 | シークレットキーを使用して行う | 公開鍵を使用して行う |
| ベストフォー | モノリシックバックエンドで、単一のサーバーが発行および検証を行う | マイクロサービス/分散API/OAuth2 |
3. JWTの一般的な脆弱性を回避する
1. "alg: none"脆弱性
いくつかの不十分なライブラリでは、algがnoneに設定されているトークンを受け入れることがあります。これにより、署名検証を回避できます。サーバーミドルウェアで許可されたアルゴリズムを明示的に強制するようにしてください。
2. アルゴリズム混乱攻撃 (HS256 vs RS256)
サーバーがRS256 (非同期)を想定しているが、HS256 (同期)を受け取った場合、攻撃者はサーバーの公開鍵をシークレットキーとして使用して署名を生成できます。トークンのアルゴリズムを検証する前に署名検証を行うようにしてください。
3. 有効期限 (exp) の欠如
有効期限が設定されていないトークンは、永久に有効です。短い有効期限 (例: 15分) を設定したアクセストークンとリフレッシュトークンを使用し、リフレッシュトークンを回転するようにしてください。
4. Teksolvrの開発者ツール
トークンを安全に検査およびデバッグするには、Teksolvrツールを使用してください。
- JWTデコード ヘッダーとクレームをデコードします。
- 正規表現テスター 正規表現検証ルールをテストします。
- パスワードおよびキー生成器 ランダムなシークレットキーを生成します。
5. 例の使用例
- 認証: REST API、マイクロサービス、シングルページアプリケーション (SPA)などでステートレス認証にJWTを使用します。
- 認可: ユーザーロールと権限を格納するためにJWTを使用し、詳細なアクセス制御を実現します。
- セッション管理: ユーザーセッションを管理するためにJWTを使用し、サーバーサイドのセッションストレージを必要とせずに済みます。
6. セキュリティのベストプラクティス
- HTTPSを使用してトークンを妨害および改ざんから保護します。
- 短い有効期限のアクセストークンとリフレッシュトークンを使用します。
- 安全なランダムな数値生成器を使用してシークレットキーを生成します。
- トークンブラックリストを実装してトークン再利用を防止します。
- 定期的にシークレットキーとリフレッシュトークンを回転します。
7. 参照
- RFC 7519: JSON Web Tokens (JWT)
- RFC 7515: JSON Web Signature (JWS)
- RFC 7516: JSON Web Encryption (JWE)
8. 画像クレジット
図名
9. トラブルシューティングチェックリスト
- トークンの署名とアルゴリズムを検証します。
- トークンの有効期限とリフレッシュトークンの回転を確認します。
- 安全なランダムな数値生成器を使用してシークレットキーを生成します。
- トークンブラックリストを実装してトークン再利用を防止します。
10. FAQ
- Q: JWTトークンとは何ですか? A: JWTトークンは、クレーム、署名、ヘッダーを含むJSONオブジェクトです。
- Q: 同期と非同期署名の違いは何ですか? A: 同期署名は共有シークレットキーを使用し、非同期署名は公開鍵/秘密鍵ペアを使用します。
- Q: "alg: none"脆弱性を回避するにはどうすればよいですか? A: サーバーミドルウェアで許可されたアルゴリズムを明示的に強制するようにしてください。
11. 結論
JSON Web Tokens (JWT)は、2つのパーティー間で安全にクレームを表現するために使用される広く使用されている方法です。ただし、JWTの検証を適切に実装しないと、認証のバイパス脆弱性を引き起こす可能性があります。セキュリティのベストプラクティスを遵守することで、信頼性の高いJWTトークンの使用を確実に実現できます。