JWT・JWSの超ざっくり理解
Table of Contents
iOSアプリを開発していると、「Sign in with Apple」やアプリ内課金に対応する際に、JSON Web Token(JWT)やJSON Web Signature(JWS)に触れることがあります。最近、それらを本格的に扱うまでは、JWT・JWSに苦手意識がありました。
しかし、JWT・JWS自体は何も悪くありません。これは安全にデータをやり取りするための仕組みにすぎず、わかりにくさの原因は、それをラップしているデータ構造にありました。
このポストでは、わかりにくいデータ構造の話は避けて、JWS・JWTの超ざっくり仕様だけをまとめます。
Base64URLデコードすると内容を読める #
JWT・JWSは、Base64URLエンコードされた文字列をピリオド(.)でつないだものです。
文字列をピリオドで分割すると、3つの部分に分けられます。
本丸となるデータは、2番目の部分(Payload)にあり、これをBase64URLデコードすると内容を読むことができます。
3番目の部分は署名(Signature)で、Payloadが改ざんされていないかを確認する際に使用します。 署名に使われたアルゴリズムは、1番目の部分(Header)に記載されています。 場合によっては証明書のチェーンが含まれることもあります。
JWT・JWSの作り方←→読み方 #
JWT・JWSは、JSONをBase64URLエンコードしたものを組み合わせた形式です。 HeaderのJSON、PayloadのJSON、それらを基にしたSignatureをそれぞれBase64URLエンコードし、ピリオドで連結します。
参考ページ: https://developer.mamezou-tech.com/blogs/2022/12/08/jwt-auth/
手順は以下のとおりです。
- HeaderのJSONをBase64URLエンコードする(
A)- Appleのアプリ内課金では、ここに証明書のチェーンが含まれることがありました。
- PayloadのJSONをBase64URLエンコードする(
B) A.Bの文字列を秘密鍵で署名し、Signatureを作成する- SignatureをBase64URLエンコードする(
C) A.B.Cの形式で連結すると完成
読む時は、これの逆をしたら良い、ということになります。
とりあえず中身だけを知りたければ、B(Payload)をBase64URLデコードするだけで済みます。
しかし、Bの部分だけを差し替えられたJWT・JWSを受け取っている可能性もあるので、改ざんチェックを行うのが理想です。その場合は、CをBase64URLデコードして公開鍵で検証し、A.Bと一致するかを確認します。
JWT・JWSの違い #
-
JWTの場合は、必須のフィールドがある RFC 7519 - JSON Web Token (JWT)
-
JWSの場合、ペイロードの内容は自由 JSONである必要はないようです1
以上が、JWT・JWSの超ざっくり理解でした。