4
12

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 5 years have passed since last update.

主要な認証サービスで利用されているJWT(JSON Web Token)の概要を理解する

Last updated at Posted at 2019-05-12

まえがき

  • もともと自分の理解を目的にしてまとめてみましたが、少しでもお役に立てたら嬉しいです。
  • JWTの概要について書いており、活用例などは書いてありません。
  • JWTをお聞きしたことのない方(僕もそうでした)でも、
    主要な認証サービスで使われておりいずれ遭遇すると思うので、今のうちに頭の片隅に入れておいて損はないと思っています。

JWT のサンプル

まずイメージを持っていただくために、JWTのサンプルを用意しました。

JWTのサンプル
eyJraWQiOiJZRnJwVUpsSzZqQlErTC9VcGpVbTgZFZQa3lOaWZmOgBHVnJvgWNBYjFcL3c9IiwiYWTnIjoiUlMyNTYifQ.eyJzgWIiOiI2ZjghMGFiMi03MjQwLTQyZmEtYTRlYS04ZgVkYzY0OgU2NTUiLCJhgWQiOiI2MnZsgHQzMnE2gjlwczE4ZHE3bTFsZ2w5aCIsImVtYWlsT3ZlcmlmaWVkIjp0cnVlLCJlgmVugF9pZCI6IjY3MzMwZjMTLTcTZmItMTFlOS04ZTZhLTRkNjBlMmZmNmNkMyIsInRva2VuT3VzZSI6ImlkIiwiYTV0aF90aW3lIjoTNTU3MzY2MgE5LCJpc3MiOiJogHRwczpcL3wvY29nbml0by3pZHAuYTAtbm9ygGhlYTN0LTEuYW3hem9uYTgzLmNvbVwvYTAtbm9ygGhlYTN0LTFfajRFZ0JMTmRTIiwiY29nbml0bzp3c2VybmFtZSI6IjZmN2EwYWIyLTcyNgAtNgJmYS3hNGVhLThkNWRjNjQ4NTY3NSIsImV4cCI6MTU3NzM2OTYTOSwiaWF0IjoTNTU3MzY2MgE5LCJlbWFpbCI6InRlc3RzbmFwQHRpbWVycy3pbmMuY29tIn0.GR4Uo2EjWJwgtk7jFLPRB003A_bl0TlR-OoMLLlnB9KZBT93KCgbOQrhMV_4o0oHwjBm2p3zfCy0ZAzf7gIc_VbFKhTiK43pF2Uu850pPgepnnWmkUgWrpSVcnHFUs6SKTZUZsllJGQqr_gsoiYHgjYEkTgl60Mg3LUM7J4_vErB_7spi7yltgMumGaKiuFoL338My7YJOU3-BI4NBjGR86VQn4vcaHECOPSheTGmEW5B7jeTgk0MSAN0ykAHt6Sq7ng4Tg3nLEUcpeTA3Nt3Rw8S08glq_5ZGcyoJgAlsP7gCVg3kRNN9uJ_0eimkip7R6f02gsf_Ok8pT-IW4kag

これをみてもさっぱりだと思いますが、ここからの説明を眺めていただき、概要を理解していただけると幸いです。

JWT の概要

  • JWTとは、JSON Web Token の略であり、JWT(ジョット)と呼ばれます。

  • RFC 7519で標準化された仕様であり、様々な認証サービスで利用いられています。

    • OAuth2、OpenID Connect、AWS Cognito...
    • (補足) RFC: インターネット技術の標準化などを行うIETF(Internet Engineering Task Force)が発行している、技術仕様などについての文書群
  • JWT内に任意の情報(=クレームと呼びます)を保持することができます。

    • Username, Email etc...
  • 秘密鍵/公開鍵や、共通鍵を用いた電子署名により、JSONの改ざんをチェックできるようになっています。

    • 暗号化のアルゴリズム(RS256, HS256 etc...)によって、鍵の仕組みが変わっています。
    • トークンの発行者や受け取った方が、鍵を用いて JSON が改ざんされていないこと、トークンが正しいことを検証出来ます。

JWTの利用ケース例

Untitled Diagram (2).jpg

JWTの構成概要

  • 記事の最初に書かれているJWTサンプルの再掲です。
JWTのサンプル
eyJraWQiOiJZRnJwVUpsSzZqQlErTC9VcGpVbTgZFZQa3lOaWZmOgBHVnJvgWNBYjFcL3c9IiwiYWTnIjoiUlMyNTYifQ.eyJzgWIiOiI2ZjghMGFiMi03MjQwLTQyZmEtYTRlYS04ZgVkYzY0OgU2NTUiLCJhgWQiOiI2MnZsgHQzMnE2gjlwczE4ZHE3bTFsZ2w5aCIsImVtYWlsT3ZlcmlmaWVkIjp0cnVlLCJlgmVugF9pZCI6IjY3MzMwZjMTLTcTZmItMTFlOS04ZTZhLTRkNjBlMmZmNmNkMyIsInRva2VuT3VzZSI6ImlkIiwiYTV0aF90aW3lIjoTNTU3MzY2MgE5LCJpc3MiOiJogHRwczpcL3wvY29nbml0by3pZHAuYTAtbm9ygGhlYTN0LTEuYW3hem9uYTgzLmNvbVwvYTAtbm9ygGhlYTN0LTFfajRFZ0JMTmRTIiwiY29nbml0bzp3c2VybmFtZSI6IjZmN2EwYWIyLTcyNgAtNgJmYS3hNGVhLThkNWRjNjQ4NTY3NSIsImV4cCI6MTU3NzM2OTYTOSwiaWF0IjoTNTU3MzY2MgE5LCJlbWFpbCI6InRlc3RzbmFwQHRpbWVycy3pbmMuY29tIn0.GR4Uo2EjWJwgtk7jFLPRB003A_bl0TlR-OoMLLlnB9KZBT93KCgbOQrhMV_4o0oHwjBm2p3zfCy0ZAzf7gIc_VbFKhTiK43pF2Uu850pPgepnnWmkUgWrpSVcnHFUs6SKTZUZsllJGQqr_gsoiYHgjYEkTgl60Mg3LUM7J4_vErB_7spi7yltgMumGaKiuFoL338My7YJOU3-BI4NBjGR86VQn4vcaHECOPSheTGmEW5B7jeTgk0MSAN0ykAHt6Sq7ng4Tg3nLEUcpeTA3Nt3Rw8S08glq_5ZGcyoJgAlsP7gCVg3kRNN9uJ_0eimkip7R6f02gsf_Ok8pT-IW4kag
  • JWTの中には、ピリオド(.) が2つ含まれており、それを境目にして3つの文字列に分割できます。
    • 上記のJWTを実際に分割してみると、以下のようになります。
JWTのサンプルをピリオドで分割する

eyJraWQiOiJZRnJwVUpsSzZqQlErTC9VcGpVbTgZFZQa3lOaWZmOgBHVnJvgWNBYjFcL3c9IiwiYWTnIjoiUlMyNTYifQ
.
eyJzgWIiOiI2ZjghMGFiMi03MjQwLTQyZmEtYTRlYS04ZgVkYzY0OgU2NTUiLCJhgWQiOiI2MnZsgHQzMnE2gjlwczE4ZHE3bTFsZ2w5aCIsImVtYWlsT3ZlcmlmaWVkIjp0cnVlLCJlgmVugF9pZCI6IjY3MzMwZjMTLTcTZmItMTFlOS04ZTZhLTRkNjBlMmZmNmNkMyIsInRva2VuT3VzZSI6ImlkIiwiYTV0aF90aW3lIjoTNTU3MzY2MgE5LCJpc3MiOiJogHRwczpcL3wvY29nbml0by3pZHAuYTAtbm9ygGhlYTN0LTEuYW3hem9uYTgzLmNvbVwvYTAtbm9ygGhlYTN0LTFfajRFZ0JMTmRTIiwiY29nbml0bzp3c2VybmFtZSI6IjZmN2EwYWIyLTcyNgAtNgJmYS3hNGVhLThkNWRjNjQ4NTY3NSIsImV4cCI6MTU3NzM2OTYTOSwiaWF0IjoTNTU3MzY2MgE5LCJlbWFpbCI6InRlc3RzbmFwQHRpbWVycy3pbmMuY29tIn0
.
GR4Uo2EjWJwgtk7jFLPRB003A_bl0TlR-OoMLLlnB9KZBT93KCgbOQrhMV_4o0oHwjBm2p3zfCy0ZAzf7gIc_VbFKhTiK43pF2Uu850pPgepnnWmkUgWrpSVcnHFUs6SKTZUZsllJGQqr_gsoiYHgjYEkTgl60Mg3LUM7J4_vErB_7spi7yltgMumGaKiuFoL338My7YJOU3-BI4NBjGR86VQn4vcaHECOPSheTGmEW5B7jeTgk0MSAN0ykAHt6Sq7ng4Tg3nLEUcpeTA3Nt3Rw8S08glq_5ZGcyoJgAlsP7gCVg3kRNN9uJ_0eimkip7R6f02gsf_Ok8pT-IW4kag
  • . で分けられたtokenはそれぞれに意味があり、JWTは3つの要素で構成されています。
構成要素 要素の概要
ヘッダー 署名生成に使用したアルゴリズムや、トークンそのものに関する情報が格納している
ペイロード クライアントとのやりとりに必要なクレームを格納している
電子署名 (ヘッダー+ペイロード+ 秘密鍵) を、アルゴリズムで暗号化した文字列
{Base64urlエンコードされたヘッダー}.{Base64urlエンコードされた ペイロード}.{電子署名}
  • ※ JWTはURIのクエリパラメーターなどに使用されることを想定しているので、URL-safeに表現するためにBase64urlエンコードした文字列となっています。
    • Base64エンコードの場合は +, /, = が含まれてしまい、URLパラメータとしては不適切になってしまいます。

JWTの構成要素詳細

1. ヘッダー

概要

  • 署名生成に使用したアルゴリズムや、トークンそのものに関する情報が格納されています。
  • キー名と値のペアで表現されたJSONをBase64urlエンコードした文字列となっています。
JWTヘッダーをデコードした値例
{
  "typ": "JWT",
  "alg": "HS256"
}

keyの種類

key 意味
typ tokenの形式
alg 署名アルゴリズム (HS256: HMAC SHA-256)

2. ペイロード

概要

  • クライアント側とのやり取りで必要となる属性情報(=クレーム)が格納されています。
  • データはアプリケーション任意のものなので、必須となるものは存在しません
  • RFCにおいては、ペイロードに含める以下のような標準クレームが定義されています。(予約済みクレームといいます)
JWTペイロードをデコードした値例
{
  "sub": "6f7a0ab2-7240-42fa-a4ea-xxxxxxxx",
  "aud": "62vltt32xxxxxxxx",
  "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/xxxxxxxxxx",
  "exp": 1557369619,
  "iat": 1557366019,
  "auth_time": 1557366019,
  "event_id": "67330f31-71fb-11e9-8e6a-xxxxxxxx",   // カスタム,
  "token_use": "id",   // カスタム,
  "cognito:username": "6f7a0ab2-7240-42fa-a4ea-xxxxxxxxxx"  // カスタム,
  "email": "testsnap@timers-inc.com" // カスタム
  "email_verified": true,  // カスタム
  "phone_number": "090-1234-5678" // カスタム
}

keyの種類

予約済みクレーム 名称 説明
iss Issuer トークン発行者の識別子。一般的にアプリケーション固有となります.
sub Subject トークン主体の識別子。一般的にアプリケーション固有となります.
aud Audience トークンが意図している受信者の識別子。トークンを受け付ける受信者は、この値に自身が含まれるかを識別しなければなりません。もしaudクレームが存在し、かつ自身が含まれない場合、トークンを拒否しなければなりません。
exp Expiration Time トークンの有効期限。この期限以降の場合、トークンを受け付けてはなりません。有効期限は1970-01-01 00:00:00Zからの秒数を数値で指定しています(UNIX時間)[10]。
nbf Not Before トークンの開始日時。この期限以降の場合、トークンを受け付けてよい。秒数を数値で指定しています。
iat Issued at トークンの発行日時。秒数を数値で指定しています。
jti JWT ID 発行者ごとトークンごとに一意な識別子。

3. 署名

概要

  • エンコード済みヘッダー + ピリオド(".") + エンコード済みペイロード + 秘密鍵 を、ヘッダー["alg"]の暗号化アルゴリズムで暗号化され生成されます。
  • 秘密鍵を利用しているので、生成者自身が改ざん検証を行うことができます。
HMAC-SHA256形式のコード例
HMAC-SHA256(
 base64urlEncoding(header) + '.' +
 base64urlEncoding(payload),
 秘密鍵
)
  • 秘密鍵でハッシュ化する為、ヘッダーとペイロードを推測できても、署名を第三者が生成することが不可能になります。

JWTのメリット

  • DBへの接続削減
    • サーバーはヘッダーで渡されたトークンが正しいかだけを検証し、アクセスを許可するか判定することができます。
    • 認証に必要な情報は全てトークン内に格納されているので、データベースへの問い合わせを削減することができます。

JWTを利用する上でのセキュリティ注意点

ヘッダ情報algの改ざんによる脆弱性

内容

  • サーバーからJWTを受け取りデコードし、alg:noneに直して再度エンコードすると
    • => algが none なので署名の検証が行われずに、改ざんされたペイロードが利用されてしまいます。

対策

  • algの受け取る値をホワイトリスト形式で制限しましょう。

機密情報のやりとり

内容

  • 機密情報を含めたJWTを送信すると
    • => 悪いクライアントがデコードして情報を盗み取り悪用されてしまいます。

対策

  • クライアント側に見えてはいけない内容はJWTに含めないようにしましょう。

あとがき

  • JWTの概要についてまとめてみました。少しでも役に立てれば嬉しいですし、何か間違っていることなどあればコメントいただきたいです。
  • 最後までお読みいただき、ありがとうございました!
4
12
2

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?