VAPID JWT

VAPID

[32] VAPIDHTTP認証認証方式の1つです。 Web Push で使われます。

仕様書

プロトコル

[24] auth-scheme として vapidMIME型として application/webpush-options+json が定義されています。

鍵と JWT データ

[16] アプリケーションサーバーは、 VAPID 署名用の鍵ペアを生成しておきます。 これは P-256 curveECDSA で使えるものでなければなりません。 このによって、 プッシュサービスは複数のプッシュメッセージ送信に渡ってアプリケーションサーバーを識別できるのであります。 >>1 2.

[22] プッシュサービスDoS攻撃のリスクに晒されており、 プッシュメッセージを送信してくるアプリケーションサーバーを識別し制限することができるようになります。 プッシュメッセージを捨てるかどうかの判断で、 行儀の良いアプリケーションサーバーを識別できないアプリケーションサーバーより優遇したりできます。 >>1 1.1.
[23] また、プッシュ資源を、 URL が秘匿されることだけに頼らず、 より確実にアプリケーションサーバーだけがプッシュメッセージを送信できるようになります。 >>1 1., 4.

[50] アプリケーションサーバーは、事前に VAPID鍵ペアを1組用意しておいて、 これをプッシュ購読の作成のときに毎回使うことが想定されています。 必要であれば、同じアプリケーションサーバーで複数の鍵ペアを使うこともできますが、 ある1つのプッシュ購読で使う鍵ペアは、特定の1組である必要があります。

[14] アプリケーションサーバーは、 プッシュメッセージのデータの暗号化に使う aes128gcmと、 VAPID で使うに違ったものを使わなければなりません>>1 3., >>259 aes128gcmはその場その場の使い捨て、 VAPIDは恒久利用、 と性質も違います。


[17] アプリケーションサーバーは、 プッシュメッセージ送信にあたって、 次のような claim を持つ JWT を作成して署名します。 >>1 2.

aud (聴衆 (audience) )
プッシュ資源URLの起源Unicode直列化でなければなりません。 この JWT は当該プッシュサービス宛となるのと同時に、 同じ起源プッシュ資源 URL すべてに対して再利用可能となります。 >>1 2. 廃止され他の場面では使われなくなった Unicode直列化がここで使われることが気にかかりますが、 プッシュサービスURL に敢えて IDN を使う必然性は無さそうなので、 ASCII直列化でも問題になることはほとんど無いでしょうか。 (しかし不安になりますね。) 値は JWT StringOrURI です。 つまり : を含むときは RFC 3986 URI とされています。ということは実は Unicode直列化JWT の構文制約違反です。
exp (有効期限 (expiry) )
それ以後本 JWT満期する時刻を指定しなければなりません要求時点から24時間を超えてはなりません>>1 2. 値は JWT NumericDate です。
sub (主題)
連絡先詳細を示したい場合、指定して構いませんmailto: URLhttps: URL を含むべきです>>1 2.1. 値は JWT StringOrURI です。 プッシュサービス運営者は、 異常に多くのデータを送ってくるアプリケーションサーバーの運営者に連絡したいなど、 理由あって連絡先を知りたいことがあります。 >>1 1.1. 一方容易に詐称可能なことに要注意です >>1 5.

[29] 類似例として From: HTTPヘッダーUser-Agent: HTTPヘッダーに連絡先を記述する慣習が提唱されたり、 一部で行われていたりしましたが、 成功したとは言い難いです。 sub も果たして有効に利用されているのでしょうか。

その他
その他任意の public claim name, private claim nameclaim を使うことができます。 しかし JWT のサイズは可能な限り小さく抑えるべきです>>1 2.2.

[20] JWTJWS を使わなければなりません署名ES256 を使わなければなりません>>1 2.


[26] アプリケーションは、 Push API利用者エージェント公開鍵を引き渡します。

[45] 指定する場合、 P-256 curve 上のX9.62 uncompressed form で符号化したものでなければなりませんDOMString の場合、それを RFC 7515 base64url 符号化したものでなければなりません>>259

[47] PushSubscriptionOptionsInit 辞書applicationServerKey メンバーは、 プッシュ購読作成時に使う公開鍵を指定するものです。 BufferSource または DOMString または null で、既定値null です。 >>46

[33] PushSubscriptionOptions インターフェイスapplicationServerKey 属性取得器 >>259 は、 次のようにしなければなりません

  1. [34] 文脈オブジェクトapplicationServerKey を返します >>259ArrayBuffer または null です >>259

[36] subscribe メソッドにおけるオプション群について applicationServerKey の正規化は、次のようにします。 >>35

  1. [37] オプション群applicationServerKeynullない場合、
    1. [38] オプション群applicationServerKeyDOMString の場合、
      1. [39] バイト列を、 オプション群applicationServerKeyRFC 7515 base64url 復号した結果に設定します。
      2. [40] バイト列失敗の場合、
        1. [41] InvalidCharacterError DOMException投げ、 ここで停止します。
      3. [42] オプション群applicationServerKey を、 バイト列ArrayBuffer に設定します。
    2. [43] オプション群applicationServerKeyP-256 curve 上の妥当な点を表さない場合、
      1. [44] InvalidAccessError DOMException投げ、 ここで停止します。

[25] 利用者エージェントは、 プッシュサービス資源要求で、公開鍵を送信します。 プッシュサービスは、作成したプッシュメッセージ購読でこれを保持します。

[27] アプリケーションサーバーは、 プッシュ資源要求auth-scheme vapid を使います。 プッシュサービスプッシュメッセージ購読の保持する公開鍵を使ってこれを検証します。

auth-scheme

[2] HTTP auth-scheme vapid は、署名した JWT と、その署名を示すものです。 >>1 3.

[9] Web Push protocol で使うことを意図しています。 >>1 3.

[4] 起源サーバーの認証に使えます。 プロキシ認証 (Proxy-Authenticate, Proxy-Authorization) で使ってはなりません>>1 3.

[5] challenge (応答) は、 auth-scheme である vapid のみ含みます。引数はありません。 >>1 3.

[6] credentials (要求) は、 auth-scheme である vapid引数として tk を指定します。 >>1 3.


[12] k 引数は、 公開鍵を指定するものです。 プッシュサービスJWT を検証できるようにするものです。 ECDSA 公開鍵を、 X9.62 uncompressed form で、 RFC 7515 base64url 符号化したものを指定します。 >>1 3.

[13] JWT を使っているのに JWK でなく uncompressed form なのは、 JWK には正準形がないことと、 サイズが小さくなるためとされています。 >>1 3.

[15] プッシュサービスは、 aes128gcm公開鍵 (keyid) と VAPID公開鍵 (k) が同一の値なら、 400 応答を返すべきです>>1 3.


[11] t 引数は、 JWT を指定するものです。 >>1 3.

[18] プッシュサービスは、 JWT署名claim非妥当なら、 403 応答を返して構いませんプッシュサービス非妥当JWT の情報を使ってはなりません>>1 2.

[19] 検証したりしなかったりして構わないということで、 相互運用性の問題になりそうですが。

[8] realm 引数は無視します。 >>1 3.

[10] 指定することが認められているのか明記されていません。

[7] 未知・未対応の引数は、 無視しなければなりません>>1 3.

[21] 使用する JWT署名の方法は固定されており、 他の署名方法などが必要になったときは別の auth-scheme が必要となります。 HTTP認証auth-scheme折衝の仕組みを流用するためとされています。 >>1 2.3.


[49] アプリケーションサーバーは、プッシュメッセージの送信時、 プッシュ購読特定アプリケーションサーバーに制限されているの場合、 アプリケーションサーバーの (プッシュ購読用の) VAPID鍵ペア秘密鍵署名した JWT を含めなければなりません>>1 4.2 これは auth-scheme vapidcredentialsAuthorization: ヘッダーで指定することによります。 プッシュメッセージの送信


[48] 妥当な vapidcredentials を含まないなら拒絶しなければなりません認証がないとき 401 応答を返せますし、 認証が非妥当なとき 403 応答を返せます。 非妥当には次のような場合があります。 >>63


[28] VAPID再生攻撃に弱いです。 HTTPS を使っていれば JWT は漏れませんし、 exp を短くすれば漏洩時の悪用のリスクは抑えられます。 >>1 5.

[30] 一方で署名計算は少なからず資源を消費するので、 DoS攻撃中に正当な要求を識別するための VAPID としては矛盾した状況に置かれています。 そこでアプリケーションサーバーJWT を再利用することが推奨 (encourage) されており、 プッシュサービスは検証結果をキャッシュできます。 >>1 5.

歴史

[3] IETF提案標準 RFC 8292 として出版されました。 >>1

[31] Web Push Parameters, https://www.iana.org/assignments/webpush-parameters/webpush-parameters.xhtml

メモ