RFC 7800 Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)
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"
}
}
-
Issuer と Presenter が異なる場合は JWT 自体が含む署名は Issuer の秘密鍵によって行われているので、JWT の署名は使えない。Presenter と Issuer が同一の場合は、単に JWT の署名を検証すれば良いと思う。 ↩︎