Open1

RFC 7800 Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)

yapooyapoo

RFC 7800 - Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)

概要

JWT を用いてキー (対象鍵または非対称鍵の秘密鍵) の保有を証明する手順が定義されている。

JWT の受け手 (Recipient) はペイロードの cfn (confirmation) クレームの値を用いて後述する検証を行うことによって、JWT の提示者 (Presenter) が当該キーを保有することを確認できる。なお JWT は Presenter ではない第三者が発行してもよく、JWT の発行者を Issuer という。

cfn クレーム

cfn は以下のように JSON オブジェクトであり、単一のキーに関する情報でなければならないとされている。本説では cfn の具体的な構造について述べる。

いずれの場合であっても、cfn は単に Presenter が保有を証明したい鍵についての情報を含めるだけなので、cfn 自体が当該鍵の保有を証明してくれるわけではない。この JWT は Recipient に鍵を特定させるために用い、鍵の保有の証明自体は追加の仕組みが必要である。

このための仕組みとして、非対称鍵の場合は Presenter が秘密鍵で署名したナンスを JWT と一緒に送る事が考えられる[1]。対象鍵の場合は Recipient が送付したチャレンジを Presenter が共通鍵で暗号化して返却することが考えられる。

JWK を用いる方法

この場合は cnf 直下の jwk というキーに JWK (RFC 7517) の形式で鍵の情報を含める。秘密鍵の保有を証明したい場合には cfn に公開鍵の情報を入れる。対象鍵の場合はその鍵自体を入れるが、対象鍵を送る場合には JWT 自体が暗号化されてやり取りされていなければならない。

以下は Section 3.2 に記載されている JWT のペイロードの例である (これは公開鍵を入れているパターンである)。

{
 "iss": "https://server.example.com",
 "aud": "https://client.example.org",
 "exp": 1361398824,
 "cnf":{
   "jwk":{
     "kty": "EC",
     "use": "sig",
     "crv": "P-256",
     "x": "18wHLeIgW9wVN6VD1Txgpqy2LszYkMf6J8njVAibvhM",
     "y": "-V4dS4UaLMgP_4fY4j8ir7cl1TXlFdAgcx55o7TkcSA"
    }
  }
}

JWE を用いる方法

主に対象鍵の保有を証明する場合で JWT 自体は暗号化されない場合、cfn クレームには対象鍵の情報をペイロードに含めた JWE を入れる。ここで JWE の暗号化のために用いられる鍵は事前に Issuer と Recipient の間で共有されていなければならない。

以下は Section 3.3 に記載の JWT のペイロードの例である。

{
 "iss": "https://server.example.com",
 "sub": "24400320",
 "aud": "s6BhdRkqt3",
 "nonce": "n-0S6_WzA2Mj",
 "exp": 1311281970,
 "iat": 1311280970,
 "cnf":{
  "jwe": "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYifQ...(以下略)"
  }
}

Key ID を用いる方法

Recipient は Key ID を下にキーを特定することができる場合は、cfn にはその Key ID のみ入れれば良い。

以下は Section 3.4 に記載の JWT のペイロードの例である。

{
 "iss": "https://server.example.com",
 "aud": "https://client.example.org",
 "exp": 1361398824,
 "cnf":{
   "kid": "dfd1aa97-6d8d-4575-a0fe-34b96de2bfad"
  }
}

キーの URL を用いる方法

JWK が特定の URL で公開されている場合には、その URL を cfn に含めれば良い。JWK ではなく JWK セットが公開されている場合は、その中の kid も追加で指定する。

以下は Section 3.5 に記載の JWT のペイロードの例である。

{
 "iss": "https://server.example.com",
 "sub": "17760704",
 "aud": "https://client.example.org",
 "exp": 1440804813,
 "cnf":{
   "jku": "https://keys.example.net/pop-keys.json",
   "kid": "2015-08-28"
  }
}
脚注
  1. Issuer と Presenter が異なる場合は JWT 自体が含む署名は Issuer の秘密鍵によって行われているので、JWT の署名は使えない。Presenter と Issuer が同一の場合は、単に JWT の署名を検証すれば良いと思う。 ↩︎