JSON Web Token (JWT) は長いランダムな文字列のように見えますが、それはドットで結合された 3 つのデータにすぎません。最初の部分は、トークンがどのように構築されたかを示しています。 2 番目の部分はクレームです。誰に対するもので、いつ有効期限が切れるか、その他発行者が記入したものです。3 番目の部分は、信頼できるサーバーがチェックできる署名です。このガイドでは、各部分、毎日目にするクレーム、トークンの読み取りと信頼の違いについて説明します。実際のトークンを検査したい場合は、それを JWT Decoder に貼り付けます。これはブラウザーで実行され、値はアップロードされません。
クイック回答
JWT は header.payload.signature です。ヘッダーとペイロードは Base64URL でエンコードされた JSON です。通常、ヘッダーには alg と typ が含まれます。ペイロードには、sub、iat、exp などのクレームとカスタム フィールドが保持されます。署名は 3 番目のセグメントです。デコードすると、それらの JSON オブジェクトが表示されます。これはトークンが本物であることを証明するものではありません。検証には信頼できるサーバー上の秘密鍵または公開鍵が必要です。
点で結合された 3 つの部分
RFC 7519 では、コンパクト JWT をピリオドで区切られた 3 つの Base64URL セグメントとして定義しています。追加のラッパーや外側の JSON はなく、通常はパディング等号もありません。で分割した場合。最後の文字列が空の場合でも (セキュリティで保護されていない alg none 形式)、常に 3 つの文字列を取得します。
- ヘッダー: トークンに関するメタデータ。ほとんどの場合、alg と typ を含む JSON。
- ペイロード: クレーム。これは API が実際に読み取るデータです。
- 署名: ヘッダーとペイロード上の暗号化タグ。このツールとこの記事では、これを不透明なバイトとして扱います。
JSON を記述できる人は誰でも、ヘッダーとペイロードを作成して Base64URL エンコードできます。そのため、最初の 2 つの部分は公開されています。 JWT を傍受した人は誰でも、それらのクレームを読むことができます。機密データは、別の形式である暗号化 (JWE) も行わない限り、JWT には属しません。
ヘッダー
ヘッダーは検証者にトークンの処理方法を指示します。これは小さな JSON オブジェクトです。最初のセグメントを Base64URL デコードすると、通常、次のように表示されます。
- alg - 署名に使用されるアルゴリズム (またはなし)。一般的な値: HS256 (共有秘密を持つ HMAC)、RS256 または ES256 (非対称キー)。
- typ - 通常は JWT。一部の発行者はそれを省略します。
- kid - サーバーが JWKS セットから適切な公開鍵を選択できるようにするためのオプションの鍵 ID。
- cty - コンテンツ タイプ、まれ、ペイロードがネストされた JWT の場合に使用されます。
危険なヘッダー フィールドは alg です。デコーダは、トークンが主張するものをすべて表示します。 alg none を尊重する単純な検証ツール、または攻撃者が RS256 を HS256 に切り替えて、HMAC シークレットであるかのように公開キーで署名できるようにする単純な検証ツールは、偽造トークンを受け入れます。これはサーバーのバグであり、ブラウザ デコーダで修正できるものではありません。 alg を証拠としてではなく、ヒントとして読んでください。
ペイロード (クレーム)
ペイロードは別の JSON オブジェクトです。 JWT 仕様では、クレームを登録名 (小さな共有語彙) と、アプリが定義するプライベートまたはパブリックのカスタム名に分割します。タイムスタンプは NumericDate 値です。ミリ秒ではなく、1970-01-01 UTC からの秒数です。
よく見かける登録クレーム
- iss - 発行者。トークン (URL または認証サーバー名) を作成した人。
- 副題。トークンが対象とするユーザーまたはサービス。
- オード - 聴衆。それを受け入れる必要がある API またはアプリ。文字列または配列を指定できます。
- exp - 有効期限。この Unix 時間以降のトークンを拒否します。
- nbf - 以前はありませんでした。この Unix 時間より前のトークンを拒否します。
- iat - で発行されました。発行者が作成したとき。
- jti - JWT ID。トークンの取り消しまたは重複排除に使用される一意の ID。
カスタムクレーム
それ以外はすべてアプリケーション データです (名前、電子メール、ロール、スコープ、テナント、または権限配列)。これらのフィールドは API にとって便利であり、デコードするだけであれば偽造も簡単です。デコーダーに貼り付けたトークン内の role: admin クレームは、発行者 (または攻撃者) がその文字列を書き込んだことを意味します。バックエンドが署名を検証し、iss、aud、および exp をチェックするまでは、アクセス許可は付与されません。
署名
3 番目のセグメントは JSON ではありません。 HS256 の場合、共有秘密を使用した ASCII 文字列 header.payload 上の HMAC-SHA256 です。 RS256 または ES256 の場合、これは同じ入力上の非対称署名です。デコーダは生の Base64URL テキストを表示するので、トークンを比較できます。そのタグを再計算したりチェックしたりすることはありません。検証にはシークレットまたは発行者の公開キーが必要で、信頼できるマシン上で検証を行う必要があります。
デコードが検証されていない
ヘッダーとペイロードの JSON を読み取るだけで、「このトークンが何を主張しているか?」という答えが得られます。トークンを受け入れるサーバーは、署名を検証し、間違った alg を拒否し、exp / nbf / iat をチェックし、iss と aud を照合する必要があります。 JWT Decoder は、ログイン用ではなく、検査とデバッグ用です。
Base64URL、通常の Base64 ではない
JWT ヘッダーとペイロードは Base64URL (RFC 4648) を使用します。Base64 と同じ 6 ビット エンコーディングですが、+ は - になり、/ は _ になり、末尾の = パディングはしばしば削除されます。これにより、クエリ文字列とヘッダー内のトークンが安全に保たれます。 JWT セグメントを汎用 Base64 ツールに貼り付ける場合は、最初に URL 文字を復元しないと、JSON がデコードされません。 Base64 エンコーダ / デコーダ は通常の Base64 用です。 JWT ツールはすでに URL アルファベットを適用しています。
作業例
JWT ドキュメントで使用される古典的なデモ トークンは、小さなヘッダーとペイロードにデコードされます。ドットで分割し、最初の 2 つの部分を Base64URL デコードすると、次のようになります。
- ヘッダー JSON: {"alg":"HS256","typ":"JWT"}
- ペイロード JSON: {"sub":"1234567890","name":"John Doe","iat":1516239022}
- iat 1516239022 は 2018-01-18 01:30:22 UTC です - トークンは実際の有効期限が設定されていた場合、何年も経過しています。
- 3 番目のセグメントは HMAC 署名です。それを見ただけでは、その秘密が正しかったかどうかは分かりません。
Bearer プレフィックスは JWT の一部ではありません。 Authorization: Bearer eyJ... は HTTP ヘッダーの規則です。 Bearer とそれに続くスペースを削除し、残りの 3 つのセグメントをデコードします。 ToolsMinify デコーダーがそれを行います。
読み取ることができるものとサーバーがチェックする必要があるもの
デバッグ時にはデコーダを使用します。認証する場合は検証ツールを使用します。
- alg、typ、および kid を読み取ると、発行者がどのキーを意図したかを確認できます。
- サブ、電子メール、またはロールを読んで、失敗したリクエストを理解できます。
- exp と iat を時計と比較して、トークンが古いかどうかを確認できます。
- サーバーは、正しい鍵と正しいアルゴリズムを使用して署名を検証する必要があります。
- サーバーは、間違った iss または aud のトークン、およびまだ有効ではない、またはすでに期限切れになっているトークンを拒否する必要があります。
- サーバーは、これらのチェックに合格するまで、すべてのクレームを信頼できないものとして扱う必要があります。
よくある間違い
- デコーダからの主張を信頼します。誰でも header.payload を組み立ててジャンク署名を残すことができます。
- alg none を受け入れるか、トークンに検証アルゴリズムを選択させます。
- パスワード、セッション シークレット、または個人データをペイロードに入れる。ペイロードは、トークンを持っている人なら誰でも読み取ることができます。
- 実稼働トークンをランダムな Web サイトに貼り付けます。トークンがマシンから流出しないように、クライアント側のデコーダを推奨します。
- この形式を暗号化された JWT (JWE) と混同します。コンパクトな JWE には 3 つではなく 5 つのセグメントがあります。
よくある質問
JWTは暗号化されていますか?
標準の署名付き JWT (JWS) は暗号化されません。ヘッダーとペイロードのみがエンコードされます。トークンを持っている人は誰でもクレームを読むことができます。暗号化されたトークンは JWE を使用するため、見た目が異なります。トークンをデコーダーに貼り付けて JSON を確認できる場合、それは機密ではありません。
デコーダが署名の検証を拒否するのはなぜですか?
検証には秘密鍵または秘密鍵所有者の公開鍵が必要です。これらを公開 Web ページに送信するのは安全ではなく、信頼できないサイトに緑色の「有効」バッジが表示されると、人々が間違った小切手を信頼するよう訓練されてしまいます。ローカルでデコードします。 API で確認してください。
alg none とはどういう意味ですか?
これは、発行者 (または攻撃者) がトークンを安全でないとしてマークしたことを意味します。 3 番目のセグメントは空です。デコーダは引き続きヘッダーとペイロードを表示できます。実稼働 API は、未署名のトークンを受け入れる明確なローカルな理由がない限り、alg none を拒否する必要があります。
exp と iat はミリ秒単位ですか?
いいえ。JWT NumericDate 値は Unix エポックからの秒数です。クレームが 1.7e12 のように見える場合は、誤って JavaScript Date.now() ミリ秒を見ている可能性があります。
ペイロードを編集した後にトークンを再構築できますか?
JSON を Base64URL に再エンコードして 3 つのセグメントを結合することはできますが、古い署名は一致しなくなります。発行者の秘密鍵または秘密鍵がなければ、新しいトークンは偽造されてしまいます。それは予想通りです。デコーダは読み取り用であり、生産トークンを鋳造するためのものではありません。
トークンを安全に検査するにはどこで行えばよいですか?
ブラウザでデコードし、文字列をアップロードしないページを使用します。 ToolsMinify の JWT Decoder がそれを行います。クリックごとのチュートリアルについては、JWT Decoder の使用方法 を参照してください。
ブラウザでトークンを検査する
JWT を貼り付けると、ヘッダー、ペイロード、署名が読み取り可能なセクションとして表示されます。何もアップロードされていません:
- JWT デコーダ - トークン、整形ヘッダー、ペイロード JSON を分割し、各部分をコピーします。
- JWT デコーダーの使用方法 - 同じツールのステップバイステップガイド。
- Base64エンコーダ/デコーダ - JWT URL アルファベットではなく、通常の Base64。
- ハッシュジェネレーター - ブラウザの SHA-256 チェックサム。 JWT署名ではありません。
- すべての開発者ツール - 完全なカテゴリインデックス。
JWT をデコード - 無料
JWT Decoder を開き、トークンを貼り付け、ヘッダーとクレームを読み取ります。署名は現状のまま表示され、検証されることはありません。すべてがブラウザ内で実行されます。