LoginSignup
6
4

JWT(JSON Web Token)についての考察

Last updated at Posted at 2023-07-13

JWT(JSON Web Token)の定義

RFC 7519によると、JWTについて以下のように定義されています。

JSON Web Token(JWT)は、2つのパーティ間で転送されるクレームを表す、コンパクトでURLセーフな手段です。 JWTのクレームは、JSON Web Signature(JWS)構造のペイロードとして、またはJSON Web Encryption(JWE)構造のプレーンテキストとして使用されるJSONオブジェクトとしてエンコードされ、クレームをデジタル署名または整合性保護することができます。メッセージ認証コード(MAC)で暗号化されています。

上記の内容が理解できることを目標に解説していきたいと思います。

結構誤解されやすいのですが、JWTは定義を見ても分かるようにそれ自体が認証について規定しているわけではなく、認証が行われる際に利用される1つの手段に過ぎないことを理解しておく必要があります。具体的な認証フローはアプリケーションやシステムに依存します。JWTは、そのフローの一部として使用され、認証情報をトークンに含めるための手段として活用されます。

余談ですが、上記で出てきたRFC(Request For Comments)`とはインターネット技術の標準化などを行うIETF(Internet Engineering Task Force)が発行している、技術仕様などについての文書群のことです。

JWTの構成

一般的にはJWTは、以下の構成の一部であるペイロードのことを指します。

図は基本から理解するJWTとJWT認証の仕組みの記事を参照させていただきました。

{base64エンコードしたヘッダー}.{base64エンコードしたペイロード}.{署名}

// 具体例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiJpby5leGFjdC5zYW1wbGUuand0Iiwic3ViIjoic2F1bXBsZSIsImV4cCI6MTY3MDA4NTMzNiwiZW1haWwiOiJzYW1wbGVAZXh0YWN0LmlvIiwiZ3JvdXBzIjoibWVtYmVyLCBhZG1pbiJ9.
wZRzbwWIclydco4ta069uPSaaimTtRFECIXksB81sdo

スクリーンショット (1242).png

上図に出てくるヘッダー、ペイロード、シグネチャの補足説明をしていきます。

ヘッダー

ヘッダーにはペイロードの種類や署名アルゴリズムを記述します。

{
    "alg": "HS256",
    "typ": "JWT"
}
  • algはBASE64URLエンコードされたヘッダーとBASE64URLエンコードされたペイロードを署名(暗号化)する際のアルゴリズムです。
  • typはペイロードのデータ種別を表すものです。

ペイロード(JWT)

ペイロード(JWT)はクレームセット(claim set)です。

本来日本語だと、クレームという言葉は企業への不満や怒りを伴うなんらかの要求や主張といった意味合いで使われると思いますが、JWTにおけるクレームとはペイロードのJSONデータの項目のことを指します。

{
  "iss": "io.exact.sample.jwt",
  "sub": "saumple",
  "exp": 1670085336,
  "email": "sample@extact.io",
  "groups": "member, admin"
}
   
claim(省略名) 項目名 説明
iss issuer JWT発行者
sub subject ユーザ識別子。userID(もしくはそれを暗号化したもの)といったユーザを識別できるためのID
exp expiration time JWT有効期限

isssubgroupsなどのキーと値の組み合わせがJWTにおけるクレームです。

また、isssubexpはJWTで予約されているクレーム名で『予約クレーム』と呼ばれます。他にも様々な予約クレームが存在します。詳細はこちらの記事を参照してください。

それに対して、上図のemailgroupsなど開発者が独自で定義可能なクレームは『プライベートクレーム』と呼ばれます。

そして、予約クレームを見て分かるように省略名で書かれています。省略名を使用することにより冒頭のJWTの定義文で書かれていたJSON Web Token(JWT)は、2つのパーティ間で転送されるクレームを表す、コンパクトでURLセーフな手段のコンパクトを実現する方法の1つになっています。

シグネチャ

実はJWTにおけるヘッダーとペイロードはBASE64URLエンコードされているだけで、BASE64URLデコードを行えば簡単に中身を見ることが出来ます。

もし宜しければ下記サイトのEncodedにJWT構成の解説の具体例とのトークンを入れてみてください。簡単にデコードされて中身を確認できます。

JWSは盗聴を防ぐものではないため、悪意をもった第三者に中身が見られる可能性があるペイロードは容易に改ざん可能ということになります。

ここで登場するのが、ペイロードが改ざんされたことを検知するために暗号鍵によって作成されたシグネチャになります。

スクリーンショット (1244).png

  1. JWTの署名をBASE64URLデコードを行う。
  2. デコードされた値を暗号鍵とヘッダーに記載されている暗号アルゴリズムを使って復号する。
  3. 複合された値とBASE64URLエンコードされたヘッダーとペイロードの値と比較する。
  4. 一致していれば改ざんされていないし、一致していなければ改ざんされている。

JWTにおけるシグネチャ(署名)とは、ペイロードの改ざんを検知するのに必須な仕組みと言えます。

JWSとJWE

最後に、JWS(JSON Web Signature)とJWE(JSON Web Encryption)について簡単に解説します。

冒頭のRSC 7519の定義文の一部で書かれていた以下の文脈にJWSとJWEが記述されています。

JWTのクレームは、JSON Web Signature(JWS)構造のペイロードとして、またはJSON Web Encryption(JWE)構造のプレーンテキストとして使用されるJSONオブジェクトとしてエンコードされ、クレームをデジタル署名または整合性保護することができます。

JWSは上記の説明にも出てきたヘッダー.ペイロード.署名のフォーマットで形成された文字列で、BASE64URLエンコードされたJWTが本物かどうか、中身が改ざんされていないかを検証する仕組みのことになります。

それに対してJWEは署名ではなく、ペイロードを暗号化する表示形式になります。

スクリーンショット (1245).png

詳細に関しては以下の記事がとてもわかりやすいと思いましたので参考に貼っておきます。

おわりに

最後まで記事をご覧いただきありがとうございました。

間違いなどありましたらご指摘いただけると幸いです:bow:

参考

6
4
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
6
4