Skip to main content
  1. Posts/

JWT・JWSの超ざっくり理解

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/

手順は以下のとおりです。

  1. HeaderのJSONをBase64URLエンコードする(A
    • Appleのアプリ内課金では、ここに証明書のチェーンが含まれることがありました。
  2. PayloadのJSONをBase64URLエンコードする(B
  3. A.Bの文字列を秘密鍵で署名し、Signatureを作成する
  4. SignatureをBase64URLエンコードする(C
  5. 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の超ざっくり理解でした。