2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JWTを3分で完全に理解する

Posted at

OAuth2.0やOpenIDConnectの説明の中でよく目にするJWTとはなにかについて。
基本的にはOpenIDFoundationのドキュメント、JWTを元にしています。

お断り

今回はJWEによる暗号化手順を含めたJWEの詳細には触れません。JWEの翻訳ドキュメントがなくて整理するのが面倒だったので。
また、JWS及びJWE(まとめてJOSEと呼ばれている)については批判も多いですが、批判されている点についても今回は触れません。

概要

JWTはJSONオブジェクト自体。JWSはJWTを署名保護する手段。JWEはJWTを暗号化する手段。
つまりJWTの中には、JWSによって署名されたJWT、JWEによって暗号化されたJWT、その両方が施されたJWTが存在します。
また、プレーンなJWTについても仕様として示されています。

JWT(JSON Web Token)とは

JWTはエンコードされたJSONオブジェクトとしてクレームのセットを表します。
JWTはBase64でエンコードされたパートを.で連結したURL-safeな文字列として表現されます。
パートの数はJWS、JWEのどちらとして利用されているかによって異なります。

上記から、JWTという単語には二つの解釈が存在しうるようです。

  • 後述するJWTクレーム・セットだけを指してJWTと呼ぶ
  • .で連結したURL-safeな文字列を指してJWTと呼ぶ

様々な筆者がどちらの解釈でJWTを使っているかは文脈で判断する必要があります。
以後に登場するJWTは全て後者の解釈で利用しています。

JWS(JSON Web Signature)とは

JSONオブジェクトをベースとした構造を用いて、デジタル署名やMACsにより保護されたコンテンツを表現するための手段。
JWT自体はBase64エンコードされただけのJSONオブジェクトなので、やりとりの間に改ざんが行われる可能性があります。
対策として、JWTにJWSによる署名を付与したり、JWEによる暗号化を施します。

クレームのセットとは

JSONオブジェクトは以下のように、0以上の名前/値のペアで表されます。RFC4627

{
    "name": "value"
}

この名前:値のペアがクレーム名:クレーム値と表現され、ひとまとめにクレームと呼ばれます。
クレームのセットと表現されているのは、複数のクレームの組み合わせのことです。

パートとは

先述の通り、JWSとしてか、JWEとしてか、利用のされ方でパートは異なります。
例として、JWSとして利用されるJWTの場合、以下の3つのパートが存在します(JWEの場合は5つ)。
なお各パートは、パート毎にURF-8のオクテット配列にした上でBase64エンコードが施されています

  • JWTヘッダ(JWSヘッダ)
  • JWTクレーム・セット(JWSペイロード)
  • JWS署名

JWTヘッダ

JWTヘッダは以下のようなJSONオブジェクトで、JWTに適用される暗号化オペレーションに関するパラメータを持ちます。

{
    "typ": "JWT",
    "alg": "RSA256"
}

JWTヘッダは、JWTがJWSを用いてデジタル署名されているならJWSヘッダ、JWEを用いて暗号化されているならJWEヘッダとも呼びます。
使用しているアルゴリズムを示すalgパラメータがnoneの場合、JWTはプレーンJWTであり、JWTヘッダはJWTヘッダでしかありません。

なお同じJSONオブジェクトなのでややこしいですが、JWTクレーム・セット以外のJSONオブジェクトの中身はパラメータと呼ばれます。
クレームと呼ばれるのはJWTクレーム・セットのJSONオブジェクトの中でだけのようです。

JWTクレーム・セット

JWTクレーム・セットは以下のようなJSONオブジェクトで、JWTによって伝搬されるメッセージをクレームのセットで表現しています。

{
    "iss":"joe",
    "exp":1300819380,
    "http://example.com/is_root":true
}

クレーム・セットにはissexpのような予約済クレームの他に、http://example.com/is_rootのような独自のクレームを含めてもよいとされます。
また、予約済クレームは必須ではないため、クレーム・セットに含まれない場合もあります。
JWTクレーム・セットは、JWTがJWSを用いてデジタル署名されているならJWSペイロードとも呼びます。
プレーンJWTの場合は、JWTクレーム・セットでしかありません。

JWS署名

JWS署名はJWSヘッダとJWSペイロードを.で連結したURL-safeな文字列に対して、JWSヘッダのalgで示したアルゴリズムで署名したものになります。
プレーンJWTの場合、JWS署名は作りようが無いですが、JWTとしては以下のように3つ目のパートに空文字が連結されます。

// 本来は改行はしない

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.

署名の検証

JWSによって利用されたJWTについては署名を検証し、改ざんされていないことを確認します。
JWSヘッダーのkidパラメータのヒントを元に、発信者から公開鍵を取得し、algパラメータのアルゴリズムと合わせて署名を検証します。
また、暗号鍵にJWK(RFC7517)が利用されている場合、JWSヘッダーのkidとJWKのkidパラメータは一致するように利用できます。

当然ですが、検証は自分で実装しません。危ないので。
鍵と必要な情報を用意したら、各言語のJWTライブラリにお任せしてしまいましょう。

まとめ

JWT、完全に理解できました。
これでOAuth2.0とOIDCのトークンの扱いも完璧です。
実際は署名の検証が終わったらトークン毎に異なる、クレーム・セットの検証が発生するのでこれで完璧では無いですけど。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?