1. はじめに
このセクションとそのサブセクションは規範的ではありません。
本仕様は、ウェブ上の決済フローで強力な認証方法を利用可能にするAPIを定義します。[webauthn-3]と同様の認証利点およびユーザープライバシー重視を提供しつつ、決済処理のニーズに対応する強化を目指しています。
同様に[webauthn-3]と、本仕様はユーザーが関与する2つのプロセスを定義します。1つ目は§ 3 登録(以前の「登録」)で、ユーザーとRelying Partyとの関係を構築します。2つ目は§ 4 認証 - 安全な決済確認の決済方法で、Relying Party(場合によっては仲介決済サービスプロバイダー経由)からのチャレンジに、ユーザーが特定の決済に同意するために応答します。
本仕様の目的には、チェックアウト時の認証の摩擦を減らすことがあり、その一側面は、ユーザーが1回の登録で可能な認証回数を最大化することです。つまり、Relying Partyの同意があれば、理想的にはユーザーが「一度登録」すれば、初回登録した加盟店のオリジンだけでなく、他の加盟店オリジン(および決済サービスプロバイダー経由)でも認証できるようにすることです。
そのため、安全な決済確認の重要な機能は、加盟店(または他の事業体)がRelying Partyの代理で認証セレモニーを開始できることです。Relying Partyは認証情報作成時に、この動作を許可するようオプトインする必要があります。
機能面では、本仕様はPaymentRequest
APIの新しい決済方法を定義し、WebAuthn拡張を追加して[webauthn-3]を決済向けデータ構造、デバイスバインディング、および決済コンテキストでAPI呼び出しを可能にするための仮定の緩和で拡張します。
1.1. ユースケース
[webauthn-3]はウェブ全体向けの一般的な認証機能を提供しますが、本仕様で定義した決済向け拡張の価値を示す以下のユースケースがあります。
オンライン取引で暗号技術に基づく認証の一般的なユースケースが確立されていると仮定します。
1.1.1. 取引確定の暗号証拠
多くのオンライン決済システムでは、支払い手段を発行する事業体(例:銀行)が認証を通じて不正利用を抑止しようとします。[webauthn-3]や本仕様により、認証器で加盟店オリジンや取引金額・通貨など重要な決済情報を暗号署名できるようになります。銀行はRelying Partyとして、署名付与された決済情報を決済承認判断時に検証できます。
銀行がプレーンな[webauthn-3]を利用する場合、検証対象の決済情報はWebAuthnのchallengeに格納する必要があります。これにはいくつかの課題があります:
-
challengeフィールドの誤用となる(本来リプレイ攻撃防止用)。 -
仕様が存在せず、各銀行が独自の決済情報フォーマットやchallengeへのエンコード方法を考案する必要があり、導入の複雑化や断片化を招く。
-
規制要件でユーザーへの決済情報表示や同意記録が必要とされる場合があり、プレーンな[webauthn-3]では
challenge利用に表示指定UXがなく対応できない。
これらの限界は次の安全な決済確認の振る舞いを動機付けています:
-
プレーン[webauthn-3]と同様、
challengeフィールドはリプレイ攻撃防止のみに使用する。 -
SPCで決済情報のフォーマットを規定する。これにより汎用的な検証コードやテスト群の開発が可能となる。
-
SPCにより、ユーザーエージェントが決済情報を必ずユーザーに提示したこと、および悪意あるウェブサイトや信頼されたサイト上の悪意あるJavaScriptコードによる迂回ができないことを保証する。
-
決済情報は
CollectedClientData辞書に格納され、JavaScriptで改ざんできません。
注: 今日、ブラウザ経由のweb決済は、TLSやiframe等ウェブ機能で十分信頼されており、現行仕様はweb決済の安全性と利便性向上を目的としています。
-
1.1.2. 加盟店による認証管理
加盟店はチェックアウト時のユーザー離脱を避け、特に認証摩擦の軽減を目指します。Relying Party(例:銀行)が[webauthn-3]による認証を利用する際、iframe内で実行するのが一般的です。しかし加盟店は、Relying Partyによる認証結果の検証は維持しつつ、認証体験の管理を望んでいます。
この制限を踏まえ、安全な決済確認では次の振る舞いを導入します:
-
SPCではRelying Party以外の事業体もRelying Partyの代理として認証情報を利用可能。Relying Partyはその認証結果を検証できます。
この機能の追加的な利点として、Relying Partyは独自の認証フロント体験を構築せずともよくなり、支払いサービスプロバイダーが加盟店のために体験構築を担う見込みです。
注: 認証体験をRelying Partyが提供したい場合、iframe経由でSPCから依然として可能です。
1.1.3. デバイスバインディングの暗号証拠
決済業界では、デバイス所有の証跡が第2要素として重要な役割を持ちます。WebAuthnでは、1つの認証情報が複数デバイスで利用可能な同期パスキーを許容しています(Web Authentication § 1.2.1 Consumer with Multi-Device Credentials)。同期はログイン用途のユーザー体験向上に役立ちますが、同期パスキーのみでは一部規制環境で求められるデバイス所有要件を満たさない懸念があります。
この懸念に対応するため、ユーザーエージェントがユーザーによって作成し、秘密鍵が1台のデバイスにのみ存在(使用)する補助的な公開・秘密鍵ペアの導入を検討します。この鍵とSPCにおけるその利用をブラウザバウンドキーと呼びます。
1.2. API利用シナリオ例
このセクションでは、安全な決済確認のシナリオと本APIの利用サンプルコード例を紹介します。なお、これらは利用例であり、API活用範囲を制限するものではありません。
1.2.1. チェックアウト時の登録
これは初回フローで、新規認証情報が発行銀行によって加盟店のチェックアウト時に作成・保存されます。
-
ユーザーは
merchant.exampleにアクセスし、購入商品を選択した後、チェックアウトフローに進みます。支払い手段情報を入力し、支払い意思(例: 「支払う」ボタン押下)を示します。 -
加盟店は支払い手段発行銀行と帯域外通信(例:他のプロトコル)でやり取りし、銀行はユーザーの認証を要求し、加盟店に銀行制御のURLをiframeで開くよう提供します。
-
加盟店は
bank.exampleへのiframeをallow属性"publickey-credentials-create"付きで開きます。 -
銀行iframe内で、銀行は従来方式(例: SMS・OTP)でユーザー本人性を確認後、SPC認証への登録をユーザーに勧めます。
-
ユーザーは銀行UXの「登録」ボタンなどで同意し、銀行はiframe内で下記例のコードを実行します。
-
ユーザーはWebAuthn登録フローを経て、新規認証情報を銀行へ返送。銀行はその認証情報を自サーバ側DBにユーザー・支払い手段に紐付け保存します。
-
認証終了後、銀行iframeは閉じ、加盟店はユーザーのチェックアウト処理を完了します。
この方法でユーザーを登録するためのサンプルコードを次に示します。なお、このサンプルコードでは、 より読みやすい promise 処理のために async/await を使用できることを前提としています。
if ( ! window. PublicKeyCredential) { /* クライアントは対応していません。エラーを処理してください。 */ } const publicKey= { // チャレンジは銀行サーバーで作成し、iframe に送信する必要があります。 challenge: new Uint8Array([ 21 , 31 , 105 /* サーバーで生成された追加のランダムな 29 バイト */ ]), // リライングパーティ: rp: { name: "Fancy Bank" , }, // ユーザー: user: { // WebAuthn の一部です。この情報は SPC では必須ではありませんが、 // 銀行サーバーが将来の取引でこのユーザーを識別するために // 使用する場合があります。同じユーザーに対して値が一貫していないと、 // そのユーザー用に複数のクレデンシャルが作成される可能性があり、 // クレデンシャル選択による UX 上の摩擦が生じるおそれがあります。 id: Uint8Array. from ( window. atob( "MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII=" ), c=> c. charCodeAt( 0 )), name: "jane.doe@email.example" , displayName: "Jane Doe" , }, // この例では、リライングパーティは ES256 または RS256 の // いずれかのクレデンシャルを受け入れますが、ES256 クレデンシャルを優先します。 pubKeyCredParams: [ { type: "public-key" , alg: - 7 // "ES256" }, { type: "public-key" , alg: - 257 // "RS256" } ], authenticatorSelection: { userVerification: "required" , residentKey: "required" , authenticatorAttachment: "platform" , }, timeout: 360000 , // 6 分 // これが SPC クレデンシャルであることを示します。これは現在、 // ブラウザーがこのクレデンシャルが SPC に関連することを認識するために必須です。 // また、この例で必要となる、クロスオリジン iframe 内での // クレデンシャル作成も可能にします。 // // 将来の仕様バージョンでは、この拡張機能の必要性がなくなる可能性があります。 extensions: { "payment" : { isPayment: true , // 許可されるアルゴリズムの任意のリストです。存在しない、または空の場合は、 // ES256 と RS256 を既定値とする pubKeyCredparams が使用されます。 // この例では ES256 と RS256 が許可され、RS256 が優先されます。 browserBoundPubKeyCredParams: [ { type: "public-key" , alg: - 257 // "RS256" }, { type: "public-key" , alg: - 7 // "ES256" } ] } } }; // 注: 次の呼び出しにより、認証器は UI を表示します。 try { const newCredentialInfo= await navigator. credentials. create({ publicKey}); // 検証と登録のために、新しいクレデンシャル情報をサーバーへ送信します。 } catch ( err) { // 受け入れ可能な認証器がない、またはユーザーが同意を拒否しました。適切に処理してください。 }
1.2.2. 加盟店サイトでの認証
これは、すでに認証情報が登録されているユーザーが取引を行う際に、発行銀行と加盟店が安全な決済確認(SPC)を利用する場合のフローです。
-
ユーザーは
merchant.exampleにアクセスし、商品を選択してチェックアウトフローに進みます。支払い手段情報を入力し、支払い意思(例:「支払う」ボタン押下)を示します。 -
加盟店は支払い手段の発行銀行と帯域外通信(例:他のプロトコル)でやり取りします。発行銀行はユーザーの認証を要求し、同時に加盟店へSPC対応を伝え、API利用に必要な情報(チャレンジや当該ユーザー・支払い手段に関連付けられた認証情報ID群等)を提供します。
-
加盟店は以下のサンプルコードを実行します。
-
ユーザーはSPC UXで表示される決済情報に同意し、続けてWebAuthn認証セレモニーを実施します。署名済み暗号文が加盟店に返送されます(
AuthenticationExtensionsPaymentOutputsでブラウザバウンドキーの出力も含まれる)。 -
加盟店は署名済み暗号文を発行銀行へ帯域外で送付します。発行銀行は暗号文を検証し、ユーザーが有効であること、どんな決済情報を表示したか、取引へ同意したかを把握します。発行銀行は取引を承認し、加盟店はユーザーのチェックアウト処理を終えます。発行銀行はブラウザバウンドキーの公開鍵、
browserBoundPublicKeyを保存します。
ユーザーを認証するためのサンプルコードを次に示します。なお、このサンプルコードでは、 より読みやすい promise 処理のために async/await を使用できることを前提としています。
/* securePaymentConfirmationAvailability はブラウザーが */ /* SPC に対応しているかどうかを示します。これは、ユーザーがこのデバイスで */ /* すぐに使用できるクレデンシャルを持っているかどうかを示すものではありません。 */ const spcAvailable= ( await window. PaymentRequest? . securePaymentConfirmationAvailability? .()) === 'available' ; if ( ! spcAvailable) { /* ブラウザーは SPC に対応していません。加盟店は従来のフローにフォールバックする必要があります。 */ } const request= new PaymentRequest([{ supportedMethods: "secure-payment-confirmation" , data: { // 銀行から取得したクレデンシャル ID のリスト。 credentialIds, rpId: "fancybank.example" , // チャレンジも銀行から取得されます。 challenge: new Uint8Array([ 21 , 31 , 105 /* 銀行で生成された追加のランダムな 29 バイト */ ]), instrument: { displayName: "FancyBank Platinum Card" , details: "****1234 | 01/29" , icon: "https://fancybank.example/card-art.png" , }, payeeName: "Merchant Shop" , payeeOrigin: "https://merchant.example" , paymentEntitiesLogos: [ { url: "https://fancybank.example/logo.png" , label: "Fancy Bank" , }, { url: "https://securenetwork.example/logo.png" , label: "Secure Network" , }, ], // 呼び出し元が要求するローカライズされた体験 locale: [ "en" ], timeout: 360000 , // 6 分 // ES256 と RS256 を既定値とする、許可されるアルゴリズムの任意のリスト。 // この例では ES256 と RS256 が許可され、ES256 が優先されます。 // ブラウザーに紐付けられた鍵は、すでに存在する場合は作成されないため、 // このリストは、ブラウザーに紐付けられた鍵を作成する必要がある場合にのみ // 使用されます。 browserBoundPubKeyCredParams: [ { type: "public-key" , alg: - 7 // "ES256" }, { type: "public-key" , alg: - 257 // "RS256" } ] }], { total: { label: "Total" , amount: { currency: "USD" , value: "5.00" , }, }, }); try { const response= await request. show(); await response. complete( 'success' ); // response.data は PublicKeyCredential であり、発行銀行による // 検証用の取引データを含む clientDataJSON を持ちます。 /* 検証のために response.data を発行銀行へ送信します */ } catch ( err) { /* SPC は使用できません。加盟店は従来のフローにフォールバックする必要があります */ }
2. 用語
- SPC 認証情報
-
本仕様で定義される振る舞いで利用可能なWebAuthn認証情報。
本仕様は、SPC認証情報が他の認証フロー(例:ログイン)においてRelying Partyにどのように使用・未使用されるかの制限意図はありません。
注: 現仕様では、Relying Partyが認証情報をファーストパーティまたはサードパーティの文脈で使用するため明示的にオプトインする必要があります。今後はすべてのWebAuthn認証情報がファーストパーティ文脈(例:Relying Partyドメイン)でSPC利用可能となり、オプトイン要件はサードパーティ利用時のみとなる方向です。
- サードパーティ対応SPC認証情報
-
SPC認証情報のうち、Relying Partyが認証情報作成時に明示的にオプトインしたことで、Relying Party以外が安全な決済確認認証に利用できるもの。
- SPC認証情報がサードパーティ対応かサイレント判定する手順
-
ユーザーエージェントがRelying Party Identifierおよび認証情報IDを与えられたときに、当該認証情報IDで表現される認証情報がサードパーティ対応SPC認証情報かどうか、ユーザー操作なしに(サイレントに)判定する未定義処理。
注: WebAuthn issue 1667参照。
- 認証情報が現デバイスで利用可能かサイレント判定する手順
-
ユーザーエージェントがRelying Party Identifierおよび認証情報IDを与えられたときに、当該認証情報IDで表現される認証情報が現デバイスで利用可能(すなわちWebAuthn Get 呼び出しで成功利用し得る)か、ユーザー操作なしに(サイレントに)判定する未定義処理。
これによりユーザーエージェントは、取引UXをユーザーへ条件付き表示することができます(=成功見込みがある場合のみ提示)。
注: このプロパティ実現にはSPC認証情報が発見可能認証情報である必要があり、現仕様ではそれを要件として明記しています。
注: このプロパティはWebAuthn Conditional UI Proposalが要件とするものに非常に類似しており、両者とSPCが共通の基盤APIでサポート可能になる見込みです。
- ブラウザバウンドキー
-
WebAuthn クレデンシャルに加えて取引詳細に署名し、 ユーザーエージェントによって単一のデバイスに結び付けられる、公開鍵・秘密鍵の鍵ペア。注: この名称は、この機能の初期実装が ブラウザー向けに作成されたため選ばれたものですが、この概念は任意のユーザーエージェントに適用できます。
- 鍵ペア
-
鍵ペアは、構造体であり、公開鍵と秘密鍵で構成され、実装定義型です。
注: 公開鍵・秘密鍵は暗号アルゴリズムごとのパラメータで、該当するのはIANA COSE Algorithmsレジストリ [IANA-COSE-ALGS-REG]にある暗号アルゴリズムです。
注: 公開鍵は登録時に
CollectedClientAdditionalPaymentRegistrationData.browserBoundPublicKeyで、決済認証時にはCollectedClientAdditionalPaymentData.browserBoundPublicKeyで返されます。注: 秘密鍵は
BrowserBoundSignature.signatureで署名作成に使われます。ユーザーエージェントは秘密鍵を輸出せず、デバイスのセキュア・エレメントに保管する場合があります。
3. 登録
ユーザーを安全な決済確認(SPC)に登録するには、Relying Partyは
navigator.credentials.create()
を
payment
WebAuthn拡張
を指定して呼び出すべきです。
注: 本仕様では、ブラウザがSPC認証情報IDをキャッシュできるようWebAuthn Conditional UI未対応時に拡張機能を定義しています。将来WebAuthnでこの機能が導入されれば、SPCから拡張要件を削除する可能性があります。SPC認証情報(拡張付き)はその他は完全なWebAuthn認証情報です。
注: 登録時、Web Authenticationでは両方
name
と
displayName
が必須ですが、userメンバーの定義により、その後の認証時に両方を表示する必要はありません。2023年10月時点では
name
の方が一貫して表示されます。開発者は各実装の動向に注意してください。
4. 認証 - セキュアペイメント確認決済方式
セキュアペイメント確認を通じて決済を認証するために、本仕様は以下を定義します:
-
決済ハンドラー、すなわちセキュアペイメント確認決済ハンドラー、与えられた決済の認証要求を処理します。
-
本決済ハンドラーのための標準化済み決済方式識別子である "secure-payment-confirmation"。
セキュアペイメント確認決済ハンドラーはユーザーと取引内容を確認した後、認証セレモニーを行い、ユーザーの認証とセレモニーを表す署名付きblobを作成します。
概念的には、セキュアペイメント確認の認証は[webauthn-3]と似ていますが、主要な転換点があります。セキュアペイメント確認は、第三者(例:加盟店)がRelying Partyの代理で認証セレモニーを呼び出し、Relying Partyから他のチャネルで取得した認証情報を渡すことを許可します。§ 1.1.2 加盟店による認証管理参照。
4.1. [payment-method-id]への登録
標準化済み決済方式のレジストリに次を追加します([payment-method-id]):
- "secure-payment-confirmation"
4.2. Payment Requestコンストラクタの変更
PaymentRequestオブジェクトのコンストラクタの手順で、新たなステップを4.3の後に追加:
-
決済方式の処理:[サブステップ1-3省略]
-
seenPMIsに"secure-payment-confirmation"が含まれ、かつseenPMIsのサイズが1を超える場合、
RangeErrorをthrowする。
-
4.3. ユーザーアクティベーション要件の変更
PaymentRequest.show()
メソッドの手順で、ステップ2と3を修正:
-
関連グローバルオブジェクトがrequest のもので、一時的アクティベーション(transient activation)がない場合、ユーザーエージェントは次を実施可能:
-
拒否されたPromiseを返すが、その理由は
"SecurityError"DOMException。
-
-
そうでなければ、ユーザーアクティベーションの消費を関連グローバルオブジェクトで行う。
注: これにより、ユーザーエージェントはユーザーアクティベーション不要となり、例えばリダイレクト認証フローでリダイレクト時点にアクティベーションがなくても対応できる。セキュリティ面は§ 11.4 ユーザーアクティベーション要件の欠如参照。
4.4. SecurePaymentConfirmationRequest
辞書型
dictionary SecurePaymentConfirmationRequest {required BufferSource ;challenge required USVString ;rpId required sequence <BufferSource >;credentialIds required PaymentCredentialInstrument ;instrument unsigned long ;timeout USVString ;payeeName USVString ;payeeOrigin sequence <PaymentEntityLogo >;paymentEntitiesLogos AuthenticationExtensionsClientInputs ;extensions sequence <PublicKeyCredentialParameters >;browserBoundPubKeyCredParams sequence <USVString >;locale boolean ; };showOptOut
SecurePaymentConfirmationRequest
辞書型は以下のメンバーを持ちます:
challenge-
リプレイ攻撃防止のため、Relying Partyがサーバ側で生成する乱数チャレンジ。
rpId-
認証情報のRelying Party識別子。
credentialIds-
与えられた支払い手段の認証情報IDリスト。
instrument-
登録画面表示や取引詳細署名時に利用する手段の名称とアイコンの説明。
timeout-
取引詳細署名要求のタイムアウトまでのミリ秒数。最大1時間。デフォルト値・許可範囲はユーザーエージェントが決定。Web Authenticationは追加タイムアウト指針あり。
payeeName-
本SPC呼び出し対象の受取人(加盟店等)の表示名。任意。
payeeOriginと併用・代用可能。 payeeOriginpaymentEntitiesLogos-
本SPC呼び出しで支払いを仲介する事業体ロゴの任意リスト(表示優先度降順)。ユーザーエージェントは一部またはすべてのロゴを必須表示ではない。§ 4.9 支払い可能か確認手順参照。
注: ロゴ表示方法は仕様で厳密規定せず、ユーザーエージェントの裁量に委ねます。ロゴ順序は重要なため、開発者は表示結果で順番調整可能。
extensions-
渡す認証情報に利用する任意のWebAuthn拡張。呼び出し元は payment拡張指定不要、 自動追加される。
注: サードパーティの SPC 呼び出しは、この dictionary が 空でない場合、プライベートデータを格納できる リライング パーティ 拡張機能への攻撃を避けるために例外を投げます。§ 11.1.3 WebAuthn 拡張機能は リライングパーティにのみ許可されるを参照してください。
browserBoundPubKeyCredParams-
ブラウザバウンドキー用暗号アルゴリズム種類の許可リスト。
注: このメンバーはブラウザバウンドキーを新規作成時のみ利用されます。
locale-
言語タグ([BCP47]参照)優先度降順リスト(任意)。ウェブサイトの言語ロケール 優先リスト language priority list [RFC4647]。ユーザーエージェントはこれをもとに言語ネゴシエーションや書式化に利用可能。
showOptOut-
取引確認UXでユーザーにオプトアウト機会を与えるかどうか。任意。デフォルトはfalse。
4.5. 決済方式の追加データ型
本決済方式の追加データ型は
SecurePaymentConfirmationRequestです。
4.6. セキュアペイメント確認の利用可能性判定API
PaymentRequest
に静的APIが追加され、開発者がセキュアペイメント確認利用可否を簡易判定できるようになります。securePaymentConfirmationAvailability()
メソッドはenumのメンバーを返し、セキュアペイメント確認が利用可能か、不可能な場合はその理由を示します。enum出力を用いることで、開発者はユーザーへ認証オプション案内で適切な誘導・通知がしやすくなります。
enum {SecurePaymentConfirmationAvailability "available" ,"unavailable-unknown-reason" ,"unavailable-feature-not-enabled" ,"unavailable-no-permission-policy" ,"unavailable-no-user-verifying-platform-authenticator" , };partial interface PaymentRequest {static Promise <SecurePaymentConfirmationAvailability >(); };securePaymentConfirmationAvailability
SecurePaymentConfirmationAvailability
enumは以下のメンバーを持ちます:
available-
ユーザーエージェントが呼び出し元フレーム内でセキュアペイメント確認API利用可と判断したことを示す。
注: この結果は、特定SPC認証情報が現時点で利用可能か否かは示しません。
unavailable-unknown-reason-
呼び出し元フレームでセキュアペイメント確認API利用不可(理由不明)。ユーザーエージェントはより具体的な理由よりも、本結果を常に返すことがある(ユーザープライバシー保護のため)。
unavailable-feature-not-enabled-
呼び出し元フレームでセキュアペイメント確認API利用不可(機能未有効)。
unavailable-no-permission-policy-
呼び出し元フレームでセキュアペイメント確認API利用不可("payment"パーミッションポリシー未付与)。
unavailable-no-user-verifying-platform-authenticator-
呼び出し元フレームでセキュアペイメント確認API利用不可(ユーザー認証可能プラットフォーム認証器未利用可能)。
注: この情報は
isUserVerifyingPlatformAuthenticatorAvailableでも取得可能だが、開発者利便性のため本APIにも含む。
securePaymentConfirmationAvailability()
を与えられたDocument
documentで呼び出した場合、ユーザーエージェントは以下の手順を実施する。必要に応じてユーザープライバシー保護やユーザーエージェント固有理由で
"unavailable-unknown-reason"
を返しても良い。
-
ユーザーエージェントがセキュアペイメント確認非対応、または対応だがユーザーエージェント固有の仕組みで機能無効の場合、 "
unavailable-feature-not-enabled" を返す。 -
documentで"payment"パーミッションポリシーが未有効なら、 "
unavailable-no-permission-policy" を返す。 -
ユーザー認証可能プラットフォーム認証器がない場合、 "
unavailable-no-user-verifying-platform-authenticator" を返す。 -
他にセキュアペイメント確認機能が稼働しない理由あれば、 "
unavailable-unknown-reason"を返す。 -
"
available"を返す。
このAPIは、SPCフロー開始前に下記のような可否判定チェックを行うのに利用できます:
const spcAvailable= PaymentRequest&& PaymentRequest. securePaymentConfirmationAvailability&& await PaymentRequest. securePaymentConfirmationAvailability() === 'available' ;
注: SPC機能検出には、staticなsecurePaymentConfirmationAvailability
を推奨し、すでに構築済みPaymentRequestオブジェクトのcanMakePayment
は利用すべきではありません。
注: 本APIのプライバシー考慮は§ 12.5 securePaymentConfirmationAvailabilityによるフィンガープリンティング参照。
4.7. Secure Payment Confirmation 機能の利用可能性
Secure Payment Confirmation の機能の利用可能性を開発者が判定できるようにするため、PaymentRequest
に静的 API が追加される。このメソッド
getSecurePaymentConfirmationCapabilities()
は、機能キーから Boolean 値へのレコードを返す。
partial interface PaymentRequest {static Promise <SecurePaymentConfirmationCapabilities >(); };getSecurePaymentConfirmationCapabilities typedef record <DOMString ,boolean >;SecurePaymentConfirmationCapabilities
SecurePaymentConfirmationCapabilities
の中のキーは、辞書式昇順にソートされていなければならない (MUST)。キーの集合には、SecurePaymentConfirmationCapability
の列挙値の集合が含まれているべきである (SHOULD)。ただしユーザーエージェントは、必要と判断したキーを省略してもよい (MAY)。詳細は
§ 12.6
getSecurePaymentConfirmationCapabilities によるフィンガープリント を参照。
ある機能に対する値が true の場合、その機能は、このユーザーエージェントの Secure Payment
Confirmation 実装において現在サポートされていることが分かっている。
ある機能に対する値が false の場合、その機能は、このユーザーエージェントの Secure Payment
Confirmation 実装において現在サポートされていないことが分かっている。
ある機能がキーとして存在しない場合、その機能のサポート状況は、このユーザーエージェントの Secure Payment Confirmation 実装において不明である。
この API により、開発者は Secure Payment Confirmation フローを開始するかどうか判断する際に、特定の機能がサポートされているかを次のように確認できる。
if ( PaymentRequest&& PaymentRequest. getSecurePaymentConfirmationCapabilities) { const capabilities= await PaymentRequest. getSecurePaymentConfirmationCapabilities(); if ( capabilities. browserBoundKeyHardware) { // When the SPC API is used, hardware backed BBKs will be available. } }
Note: この API に関するプライバシー上の考慮事項については、 § 12.6 getSecurePaymentConfirmationCapabilities によるフィンガープリント を参照のこと。
4.7.1. SecurePaymentConfirmationCapability
列挙型
enum SecurePaymentConfirmationCapability {"browserBoundKeyHardware" , };
この列挙型は、開発者が評価してユーザーに特定のワークフローや体験を提供できる、限定された Secure Payment Confirmation 機能の集合を定義する。
browserBoundKeyHardware-
Secure Payment Confirmation API が、デバイス上のハードウェアセキュアエレメントに保存された ブラウザバウンドキー を利用できることを示す。
詳細は § 6 Browser Bound Key Store を参照。
4.8. 支払方法データを検証する手順
この支払方法に対する、入力 PaymentRequest
request と SecurePaymentConfirmationRequest
data の
支払方法データを検証する手順は次のとおりである。
Tests
-
data["
credentialIds"] が空の場合、RangeErrorを投げます。 -
data["
credentialIds"] 内の各 id について:-
id が空の場合、
RangeErrorを投げます。
-
-
data["
instrument"]["displayName"] が空の場合、TypeErrorを投げます。 -
data["
instrument"]["icon"] が空の場合、TypeErrorを投げます。 -
data["
instrument"] ["icon"] に対して URL パーサーを実行します。 これが失敗を返す場合、TypeErrorを投げます。 -
data["
instrument"]["details"] が存在するが空の場合、TypeErrorを投げます。 -
data["
payeeName"] と data["payeeOrigin"] の両方が省略されている場合、TypeErrorを投げます。 -
data["
payeeName"] または data["payeeOrigin"] のいずれかが存在し、 空の場合、TypeErrorを投げます。 -
data["
payeeOrigin"] が存在する場合:-
parsedURL を、 data["
payeeOrigin"] に対して URL パーサーを実行した結果とします。 -
parsedURL が失敗である場合、
TypeErrorを投げます。
-
-
data["
paymentEntitiesLogos"] が 存在し、かつ空でない場合: -
data["
extensions"] が存在し、 かつ空でなく、さらに data["rpId"] が request の関連する設定オブジェクトの オリジンでない場合、TypeErrorを投げます。 -
注:
localeは、特定の入力 メンバーに関連付けられた言語または書字方向のメタデータとは異なります。 これは、特定の文字列値についての表明ではなく、呼び出し元が要求するローカライズされた 体験を表すためです。 詳細については、§ 14 国際化に関する考慮事項を参照してください。
4.9. 支払いが可能かどうかを確認する手順
この支払方法に対する、入力 SecurePaymentConfirmationRequest
data に関する
支払いが可能かどうかを確認する手順は次のとおりである。
Tests
-
もし data["
payeeOrigin"] が存在するなら:-
parsedURL を、data["
payeeOrigin"] に対して URL パーサーを実行した結果とする。 -
parsedURL が failure ではないことをアサートする。
-
parsedURL のscheme が "
https" であることをアサートする。
NOTE: これらの前提条件は、以前に 支払方法データを検証する手順 の中でチェックされている。
-
data["
payeeOrigin"] を、parsedURL のorigin のシリアライズ結果に設定する。
-
-
icon について、«["
src" → data["instrument"]["icon"]]» を image に渡して、画像リソースを取得する。これが失敗した場合:-
もし data["
instrument"]["iconMustBeShown"] がtrueなら、falseを返す。 -
それ以外の場合、data["
instrument"]["icon"] を空文字列に設定する。Note: これにより、出力の
instrumentの icon 文字列が空であるため、RP は指定されたアイコンが表示されなかったことを認識できる。
Note: 資格情報が一致するかどうかにかかわらず、アイコンの画像リソースは取得されなければならない。 これは資格情報 ID の存在をプローブする試みを防ぐためである。
-
-
オプションとして、ユーザーエージェントは data["
paymentEntitiesLogos"] から、リストの末尾から先頭へ向かう形でエントリを削除してもよい。Note: これにより、ユーザーエージェントは表示するロゴの数を制御できる一方で、ロゴが呼び出し元にとっての表示優先度の降順であるという意味付けは保たれる。
-
data["
paymentEntitiesLogos"] 内の各 logo について:-
logo について、«["
src" → logo["url"]]» を image に渡して画像リソースを取得し、結果をデコードする。 -
取得またはデコードのいずれかが失敗した場合、logo["
url"] を空文字列に設定する。Note: これにより、出力の
paymentEntitiesLogosシーケンスの該当ロゴについて url 文字列が空になるため、RP は指定されたロゴが表示されなかったことを認識できる。
Note: 資格情報が一致するかどうかにかかわらず、ロゴの画像リソースは取得されなければならない。 これは資格情報 ID の存在をプローブする試みを防ぐためである。
-
-
data["
credentialIds"] 内の各 id について:-
現在のデバイスでクレデンシャルが利用可能かどうかを サイレントに判定する手順を実行し、 data["
rpId"] と id を渡します。 結果がfalseの場合、id を data["credentialIds"] から削除します。 -
data["
rpId"] が request の関連する設定オブジェクトのオリジンで ない場合、 SPC クレデンシャルがサードパーティ対応かどうかを サイレントに判定する手順を実行し、 data["rpId"] と id を渡します。結果がfalseの場合、id を data["credentialIds"] から削除します。
-
-
trueを返す。
4.10. 取引確認 UX の表示
PaymentRequest.show()
が呼び出され、(そのアルゴリズムの手順 19–24 において)Secure Payment Confirmation 支払ハンドラー
が選択されたとき、ユーザーエージェントは、
先に進むかどうか、どのように進みたいかをユーザーが選択できるユーザーインターフェースを提示しなければならない (MUST)。
4.10.1. ユーザーに提示される情報
ユーザーエージェントの実装選択を制限しないように、この仕様は特定のユーザーインターフェースの表示を要求しない。
しかし、Relying Party が
CollectedClientPaymentData
に含まれる情報を信頼できるようにするため、
ユーザーエージェントは、以下の内容がユーザーに伝えられ、かつ認証に対するユーザーの同意が収集されることを保証しなければならない (MUST)。
-
存在する場合、
payeeName。 -
存在する場合、
payeeOrigin。 -
instrumentの詳細、すなわち支払インストゥルメントのdisplayName、details、 およびicon。 入力のiconから画像リソースを取得またはデコードできなかった場合、 ユーザーエージェントはアイコンを表示しないか、汎用的な支払インストゥルメントアイコンを代わりに表示してもよい。NOTE: 指定されたアイコンを取得またはデコードできなかった場合、
iconMustBeShownはここではfalseでなければならない。そうでなければ、 支払いが可能かどうかを確認する手順は以前に失敗しているはずである。 -
空でない場合、
paymentEntitiesLogosのエントリ中のurlによって表現されるロゴ。-
ユーザーエージェントは、各
PaymentEntityLogoのlabelを表示する必要はないが、アクセシビリティのために使用するべきである (SHOULD)。 これらのlabelは、CollectedClientAdditionalPaymentDataに含まれ、署名対象にもなり続ける。
-
ユーザーエージェントは、存在する場合、
locale
の情報を利用して、Web サイトのものと一致する言語およびロケールに基づく書式でローカライズされた UX を表示してもよい。
もし showOptOut
が true なら、ユーザーエージェントは、ユーザーが
given relying party
に対するこの処理からオプトアウトしたいことを示す機会を与えなければならない (MUST)。
4.10.2. 取引確認 UX の結果
ユーザーエージェントは、先に進むかどうか、およびどのように進むかについて、ユーザーが次のいずれかの選択肢を示せるようにしなければならない (MUST)。
- ユーザーが支払いを続行したく、認証に SPC Credential を使用したい場合
-
ユーザーが操作している
PaymentRequestに対して、 ユーザーが支払リクエストを受諾するアルゴリズム を実行する。 - ユーザーが支払いを続行したいが、
data["
credentialIds"] が空であるか、 SPC Credential を使用したくない場合 -
次の手順を実行する:
-
data["
credentialIds"] を空リストに設定する。Note: これにより、
PaymentRequest.show()のプロミスは "NotAllowedError"DOMExceptionで拒否される。詳細は § 4.11 支払リクエストへの対応手順 を参照。 -
ユーザーが操作している
PaymentRequestに対して、 ユーザーが支払リクエストを受諾するアルゴリズム を実行する。
-
- ユーザーが支払いを続行したくない場合
-
ユーザーが決済リクエストを中止する アルゴリズムを、ユーザーが操作している
PaymentRequestに対して実行する。Note: これにより、
PaymentRequest.show()のプロミスは "AbortError"DOMExceptionで拒否される。 - ユーザーが
given relying partyに対するこの処理からオプトアウトしたい場合 -
"
OptOutError"DOMExceptionでPaymentRequest.show()を拒否する。 § 12.7 User opt out を参照。Note: この選択肢は、
showOptOutがtrueに設定されている場合にのみユーザーに提供されなければならない。
4.10.3. テスト自動化サポート
current transaction automation mode が
"none" でない場合、ユーザーエージェントはまず、自身が自動化コンテキスト内にいることを検証するべきである (should)
(WebDriver のセキュリティ上の考慮事項を参照)。その後、
ユーザーエージェントは上記の情報伝達およびユーザー同意の取得をバイパスし、代わりに
current transaction automation mode
の値に基づいて次のように振る舞うべきである。
- "
autoAccept" -
ユーザーが取引の詳細を確認し、承認したかのように振る舞う。
- "
autoChooseToAuthAnotherWay" -
ユーザーが取引の詳細を確認し、承認したが、認証に SPC Credential を使用したくないことも示したかのように振る舞う。 もし data["
credentialIds"] が空であれば、これは "autoAccept" と同等である。 - "
autoReject" -
ユーザーが取引の詳細を確認し、それを拒否した(つまり、取引を続行したくない)かのように振る舞う。
- "
autoOptOut" -
ユーザーが取引の詳細を確認し、オプトアウトしたいことを示したかのように振る舞う。
4.11. 支払リクエストへの対応手順
この支払方法に対する、与えられた PaymentRequest
request および SecurePaymentConfirmationRequest
data に対する
支払リクエストへの対応手順は次のとおりである。
Note: これらの手順は、ユーザーが 取引確認 UX を受諾した場合にのみ実行される。 これらは ユーザーが支払リクエストを受諾するアルゴリズム から呼び出される。
-
もし data["
credentialIds"] が空であれば、 "NotAllowedError"DOMExceptionを投げる。 これは、ユーザーが SPC を使用できない、または使用したくない場合における Authentication Ceremony Privacy を維持する。Note: ここで throw すると、
PaymentRequest.show()のプロミスは "NotAllowedError"DOMExceptionで拒否される。 -
topOrigin を、request の関連設定オブジェクトのトップレベルオリジンとする。
-
payment を、新しい
AuthenticationExtensionsPaymentInputs辞書とし、そのフィールドを次のようにする:isPayment-
ブール値
true。 rpId-
data["
rpId"] topOrigin-
topOrigin
payeeName-
存在する場合は data["
payeeName"]、 そうでなければ省略。 payeeOrigin-
存在する場合は data["
payeeOrigin"]、 そうでなければ省略。 paymentEntitiesLogos-
存在しかつ空でない場合は data["
paymentEntitiesLogos"]、 そうでなければ省略。この仕様の現行バージョンでは、
PaymentEntityLogoごとに 1 つの URL のみをサポートする。そのため、データ構造をそのままコピーして署名すれば、ユーザーに何が表示されたかを示すのに十分である。 将来のバージョンでは、たとえばダークモードのネイティブサポートのために、PaymentEntityLogoごとに複数の URL を追加するかもしれない。その場合、この仕様は、あるPaymentEntityLogoについてどの URL が表示されたかを Relying Party に示す必要がある。 total-
request.[[details]]["
total"] instrument-
data["
instrument"] browserBoundPubKeyCredParams-
data["
browserBoundPubKeyCredParams"]
-
extensions を、新しい
AuthenticationExtensionsClientInputs辞書とし、そのpaymentメンバーを payment に設定し、その他のメンバーを data["extensions"] から設定する。 -
publicKeyOpts を、新しい
PublicKeyCredentialRequestOptions辞書とし、そのフィールドを次のようにする:challenge-
data["
challenge"] timeout-
data["
timeout"] rpId-
data["
rpId"] userVerificationextensions-
extensions
Note: このアルゴリズムは、
userVerificationの値として "required" をハードコードしている。これは Chrome の初期実装がサポートする値であるためである。 現在の制限は将来的に変わる可能性がある。作業グループは、("preferred" や "discouraged" など)他の値のサポートによって恩恵を受けるユースケースの共有を実装者に求めている。 -
data["
credentialIds"] 内の各 id について:-
descriptor を、新しい
PublicKeyCredentialDescriptor辞書とし、そのフィールドを次のようにする:typeid-
id
transports-
長さ 1 のシーケンスで、その唯一のメンバは
internalである。
-
追加により、 descriptor を publicKeyOpts["
allowCredentials"] に加える。
-
-
outputCredential を、 «["
publicKey" → publicKeyOpts]» を渡して 資格情報を要求するアルゴリズムを実行した結果とする。Note: Chrome の初期実装は、 資格情報を要求する に対して
data.credentialIdsの全リストを渡さない。代わりに、リスト内から現在のデバイスに一致する 1 つの資格情報を選び、それだけを渡す。Note: これは [webauthn-3] の Get 挙動をトリガーする。
-
outputCredential を返す。
5.
WebAuthn拡張 - "payment"
このクライアント 登録拡張および 認証拡張は、認証情報がそれぞれSecure Payment Confirmation向けに作成または利用されることを示します。
登録時には、この拡張がブラウザによるSecure Payment Confirmation認証情報IDの識別・キャッシュを可能にします。認証時には、第三者がRelying Partyの代理で認証セレモニーを行えるようにし、署名暗号文に取引情報を追加します。
特に、ウェブサイトはnavigator.credentials.get()を使って直接この拡張を呼び出すべきではありません。認証用途の拡張は、PaymentRequestの"secure-payment-confirmation"決済方式を介してのみ利用可能です。
注:
以前はpayment拡張でクロスオリジンiframe内で認証情報作成が可能でしたが、WebAuthnではWebAuthn PR #1801以降、デフォルト対応となっています。
テスト
このテストは仕様記述の各行に直接対応するものではなく、クロスオリジンiframe内から認証処理が可能なことを検証します。この挙動は禁じる記述がないことで仕様化されています。
- 拡張子識別子
-
payment - 操作の適用範囲
- クライアント拡張入力
-
partial dictionary AuthenticationExtensionsClientInputs {AuthenticationExtensionsPaymentInputs ; };payment dictionary {AuthenticationExtensionsPaymentInputs boolean ;isPayment sequence <PublicKeyCredentialParameters >; // Only used for authentication.browserBoundPubKeyCredParams USVString ;rpId USVString ;topOrigin USVString ;payeeName USVString ;payeeOrigin sequence <PaymentEntityLogo >;paymentEntitiesLogos PaymentCurrencyAmount ;total PaymentCredentialInstrument ; };instrument isPayment-
拡張がアクティブであることを示す。
rpId-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
topOrigin-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
payeeName-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
payeeOrigin-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
paymentEntitiesLogos-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
total-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
instrument-
認証時のみ使用し、登録時には使用しない。ウェブ開発者が直接設定すべきでない。
browserBoundPubKeyCredParams-
ブラウザバウンドキー用暗号アルゴリズム種類の許可リスト。認証時はウェブ開発者は
SecurePaymentConfirmationRequest.browserBoundPubKeyCredParamsを設定すること。注: このメンバー未設定時、デフォルトは
PublicKeyCredentialCreationOptions.pubKeyCredParams。
- クライアント拡張処理(登録)
-
新規認証情報作成時:
-
ステップ3の後に下記ステップを挿入:
-
下記のいずれかが真なら:
-
pkOptions["
authenticatorSelection"]["authenticatorAttachment"] が "platform" でない。 -
pkOptions["
authenticatorSelection"]["residentKey"] が "required" または "preferred" でない。 -
pkOptions["
authenticatorSelection"]["userVerification"] が "required" でない。
その場合、
TypeErrorを投げます。注: これらの値はChrome初期実装仕様に合わせてハードコードされています。現状の制限は将来変更される可能性があります。他値サポートで有益なユースケースは実装者からの情報提供を募集しています。
-
-
-
ステップ13(
CollectedClientData作成)の前に。テスト
-
bbk_allowed_algorithmsを
browserBoundPubKeyCredParamsとする。 -
browserBoundPubKeyCredParamsが空の場合は、bbk_allowed_algorithmsをPublicKeyCredentialCreationOptions.pubKeyCredParamsとする。 -
bbk_and_algorithm、bbk_idをbbk_allowed_algorithmsで鍵ペア作成で得る。
-
(bbk_and_algorithm, bbk_id)がnullなら、以降のbbk_and_algorithm及びbbk_public_key関連手順は省略。
-
bbk_public_keyをbbk_and_algorithmでブラウザバウンド公開鍵取得で得る。
-
-
ステップ13では
CollectedClientDataの代わりに、フィールドが:CollectedClientPaymentDataを作成する。フィールドについて:payment-
CollectedClientAdditionalPaymentRegistrationDataで初期化、フィールドは:browserBoundPublicKey-
bbk_public_key - COSE_Key形式の公開鍵。
- 他フィールド
-
他のフィールドは従来ステップ13通り。
-
ステップ22、"いずれかの認証器が成功"ケース内、ステップ3(pubKeyCred返却直前):
-
鍵ペアバインドをbbk_idとpubKeyCred.
[[identifier]]で行う。失敗時はUnknownError返却。 -
payment_outputsを
AuthenticationExtensionsPaymentOutputsで初期化、フィールドは:browserBoundSignature-
BrowserBoundSignatureで初期化、フィールドは:signature-
create credential step 14でのbbk_and_algorithm及びclientDataJsonでブラウザバウンド署名生成の結果。
-
[[clientExtensionsResults]]["payment"]にpayment_outputsを設定。
-
-
- クライアント拡張処理(認証)
-
AuthenticationExtensionsPaymentInputsextension_inputsでアサーション実行時:-
"secure-payment-confirmation"決済ハンドラー外の場合、"
NotAllowedError"DOMExceptionを返す。注: SPCの拡張機能を取引UXを経ずに使う試みの防止。
-
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)内:-
6.1(options.rpIdとeffectiveDomainの比較)をスキップ。
注: クロスドメイン認証セレモニーを可能化。§ 1.1.2 加盟店による認証管理参照。
-
ステップ10の前(CollectedClientData作成前):
-
allowed_algorithmsを
SecurePaymentConfirmationRequest.browserBoundPubKeyCredParamsとする。 -
bbk_and_algorithmをcredential_idおよびallowed_algorithmsでブラウザバウンドキー取得/生成で得る。
-
-
ステップ10では
CollectedClientDataの代わりに、下記フィールドでCollectedClientPaymentDataを作成:-
typeを"payment.get"に設定。 -
paymentを新規CollectedClientAdditionalPaymentDataで初期化、フィールドは:rpId-
extension_inputs["
rpId"] topOrigin-
extension_inputs["
topOrigin"] payeeName-
存在時はextension_inputs["
payeeName"]、不在時は省略。 payeeOrigin-
存在時はextension_inputs["
payeeOrigin"]、不在時は省略。 paymentEntitiesLogos-
存在時はextension_inputs["
paymentEntitiesLogos"]、不在時は省略。 total-
extension_inputs["
total"] instrument-
extension_inputs["
instrument"] browserBoundPublicKey-
bbk_and_algorithm非null時はbbk_and_algorithmでブラウザバウンド公開鍵取得の結果。null時は未設定。
-
他フィールドは従来ステップ10通り。
-
-
"いずれかの認証器が成功"時、ステップ2で
[[clientExtensionsResults]]設定時:-
payment_outputsを
AuthenticationExtensionsPaymentOutputsで初期化、フィールドは:browserBoundSignature-
bbk_and_algorithm非null時は、
BrowserBoundSignatureで初期化、フィールドは:signature-
create credential step 14でのbbk_and_algorithm及びclientDataJsonでブラウザバウンド署名生成の結果。
-
Set
[[clientExtensionsResults]]["payment"]にpayment_outputsを設定。
-
-
-
- クライアント拡張出力
-
partial dictionary AuthenticationExtensionsClientOutputs {AuthenticationExtensionsPaymentOutputs ; };payment dictionary {AuthenticationExtensionsPaymentOutputs BrowserBoundSignature ; };browserBoundSignature dictionary {BrowserBoundSignature required ArrayBuffer ; };signature browserBoundSignature-
ブラウザバウンド署名の出力
signature-
ブラウザバウンド署名処理の成果物。
- 認証器拡張処理
-
なし
5.1. CollectedClientPaymentData
辞書
dictionary CollectedClientPaymentData :CollectedClientData {required (CollectedClientAdditionalPaymentData or CollectedClientAdditionalPaymentRegistrationData ); };payment
CollectedClientPaymentData
辞書は
CollectedClientDataを継承します。
以下の追加フィールドを含みます:
payment-
署名される追加の決済情報。
5.2. CollectedClientAdditionalPaymentData
辞書
dictionary CollectedClientAdditionalPaymentData {required USVString ;rpId required USVString ;topOrigin USVString ;payeeName USVString ;payeeOrigin sequence <PaymentEntityLogo >;paymentEntitiesLogos required PaymentCurrencyAmount ;total required PaymentCredentialInstrument ;instrument USVString ; };browserBoundPublicKey
CollectedClientAdditionalPaymentData
辞書は以下のフィールドを含みます:
rpId-
この認証情報を作成した Relying Party の ID。
NOTE: 歴史的な理由により、一部の実装ではこのパラメーターを
rpという名前でも併せて含めている場合がある。 両方が存在する場合、rpとrpIdの値は同一でなければならない。 topOrigin-
取引詳細の署名を要求したトップレベルコンテキストのオリジン。
payeeName-
存在する場合、ユーザーに表示された受取人(payee)の名称。
payeeOrigin-
存在する場合、ユーザーに表示された受取人のオリジン。
paymentEntitiesLogos-
取引ダイアログ内でユーザーに表示されたロゴ(存在する場合)。これらのロゴは、この取引を仲介するエンティティを表すことを意図している。
total-
[payment-request] の
totalフィールドに対応する、PaymentCurrencyAmount。 instrument-
ユーザーに表示された支払手段(インストゥルメント)の情報。
browserBoundPublicKey-
ブラウザバウンドキー の公開鍵を base64url エンコーディングした値。 WebAuthn における Base64url encoding を参照。
呼び出しフレームのオリジンは既にCollectedClientData([webauthn-3])に含まれているため、CollectedClientAdditionalPaymentData
に paymentRequestOrigin フィールドはありません。
5.3. CollectedClientAdditionalPaymentRegistrationData
辞書
dictionary CollectedClientAdditionalPaymentRegistrationData {USVString ; };browserBoundPublicKey
CollectedClientAdditionalPaymentRegistrationData
辞書は以下のフィールドを含みます:
browserBoundPublicKey-
ブラウザバウンドキーの公開鍵を base64url エンコーディングした値。WebAuthn における Base64url encoding を参照。
6. Browser Bound Key ストア
これはユーザーエージェントが所有する内部コンポーネントであり、 SPC クレデンシャル(すなわちパスキー)との関連付けを含む、 プラットフォーム依存の暗号鍵ペアを管理します。各ブラウザー紐付け鍵ストアは、単一の ユーザーエージェントによって所有され、そのユーザーエージェントがそれをデバイスとブラウザーの両方に紐付けます。各 ユーザーエージェントは、たとえばユーザーエージェントに複数のプロファイルがある場合などに、 複数のブラウザー紐付け鍵ストアを保持できます。 このセクションでは、ブラウザー紐付け鍵 ストアと、ブラウザー紐付け鍵ペアを作成、紐付け、取得、およびそれを使用して署名するための手順について説明します。
注: ブラウザー紐付け鍵ストアは、 鍵ペアの生成、鍵ペアの取得、公開鍵のエクスポート、および署名の生成を行う必要があります。多くのオペレーティングシステムは、 これらの操作を実装し、利用可能な場合にはデバイス上のセキュアエレメントに秘密鍵を保存する API を提供しています。たとえば、 Android KeyStore、 Apple CryptoKit、または Windows Cryptography API: Next Generation などです。
注: ブラウザー紐付け鍵の要件と設計上の考慮事項は、 BBK 要件 文書に記述されています。 ブラウザー紐付け鍵ストアとその手順の設計は、これらの要件と 考慮事項に基づいています。 要件文書内では、「installed browser program」という用語がユーザーエージェントを指すために使用されています。これは その文書がブラウザー実装を念頭に書かれたためです。しかし、これらの要件と設計上の 考慮事項は、任意のユーザーエージェント実装に適用できます。
ブラウザー紐付け鍵ストアには、次のものが含まれます。
- browser_bound_map
-
Credential ID から鍵ペア識別子へのマップ。
注: 各鍵ペア識別子は、最大 1 つの Credential ID と関連付けることができます。
- keypair_map
-
バイト配列である鍵ペア識別子から、 公開鍵・秘密鍵のタプル、 鍵ペア、およびアルゴリズム識別子である
COSEAlgorithmIdentifierへのマップ。注: ユーザーエージェントは、 keypair_map と同等のものを提供する 暗号 API を使用している場合があり、その場合、ユーザーエージェントはこの側面を暗号 API に委譲します。
6.1. 鍵ペアの作成
鍵ペアを作成する手順は、PublicKeyCredentialParameters
型の allowed_algorithms を与えられ、タプルとして鍵ペアとその COSEAlgorithmIdentifier
と鍵ペア識別子のバイト配列を返すように、以下の手順を実行します:
注: 許可されたアルゴリズムまたはデフォルトの許可アルゴリズムから鍵ペアを生成します。
-
もし allowed_algorithms が 空 であれば、このリストを以下を順に含むデフォルトリストに設定します:
-
type=PublicKeyCredentialTypeかつalg= -7 ("ES256"). -
type=PublicKeyCredentialTypeかつalg= -257 ("RS256").
-
-
Remove を使って、allowed_algorithms から
PublicKeyCredential型でないエントリを削除します。 -
Remove を使って、ユーザーエージェントがサポートしていないエントリをallowed_algorithmsから削除します。
注: ユーザーエージェントはデバイスプラットフォームごとに異なる暗号アルゴリズムセットをサポートする可能性があります。
-
もし allowed_algorithms の size が 0 であれば、null を返します。
注: この場合、ユーザーエージェントはブラウザバウンド出力を追加しません。
-
もし allowed_algorithms の size が 0 より大きければ、以下を実行:
-
chosen_algorithm を allowed_algorithms[0] とする。
-
chosen_algorithm に対応する既定手順で公開・秘密鍵の鍵ペアを生成し、その結果を bbk とする。鍵生成アルゴリズムについては IANA COSE Algorithms レジストリ [IANA-COSE-ALGS-REG] を参照してください。生成が失敗した場合は null を返す。
-
bbk_and_algorithm を (bbk, chosen_algorithm) の タプルとする。
-
bbk_id を次のいずれかとする:
-
長さ32の配列として初期化されたバイト配列:
-
bbk_id を長さ32の配列とする。
-
getRandomValues(bbk_id) を呼ぶ。
-
-
実装定義の鍵生成手順から得られる鍵ペアハンドルのシリアライズ結果のバイト配列。このバイト配列は、後に ブラウザバウンドキーの取得/作成 の際に鍵を識別するためのものでなければならない。
注: 多くの暗号APIは秘密鍵の代わりに識別子、ハンドル、またはラップされた鍵を返し、公開鍵と共に返す場合があります。例えば秘密鍵がセキュアエレメントに格納されている場合、秘密鍵自体はユーザーエージェントに直接利用可能でないため、識別子/ハンドル/ラップ鍵を暗号APIの別関数に渡して使用する必要があります。
-
-
Set を使って keypair_map[bbk_id] に bbk_and_algorithm を設定する。
-
(bbk_and_algorithm, bbk_id) を返す。
-
仕様はハードウェアストレージ内のアルゴリズムを優先し(与えられた順序で)、次にソフトウェア内のアルゴリズムを優先するよう規定できる可能性があります。現時点では Chrome がプラットフォームごとに1つのアルゴリズムのみハードウェアでサポートする予定であるため、この話題は当面重要でないかもしれません。BBK のストレージ種別や許容ストレージ種別、ストレージ種別を Relying Party に公開することなどに関する議論は Secure Payment Confirmation issue #288 を参照してください。
6.2. 鍵ペアのバインド
鍵ペアをバインドするには、 鍵ペア識別子を含むバイト配列 bbk_id と、バイト配列 credential_id が与えられたとして、失敗を返す可能性があり、 次の手順を実行します:
注: browser_bound_map 内に、 Credential ID(すなわちパスキー識別子)に対する ブラウザー紐付け鍵識別子を格納します。
-
設定 browser_bound_map[credential_id] を bbk_id に設定します。 エラー
InvalidStateError、TypeErrorおよびQuotaExceededErrorを捕捉し、その場合は失敗を返します。注: エラーは、
write(buffer, options)のような 基盤となるファイルシステム操作によって投げられる場合があります。 ここでは false が返され、これによりユーザーエージェントは 取引にブラウザー紐付け鍵を含めることを避けます。この場合、 リライングパーティはこの取引でブラウザー紐付け鍵を取得しません。 後続の支払いアサーションでは、新しい鍵ペアの 作成が試みられます。
6.3. 鍵ペアの取得
ブラウザー紐付け鍵を取得または
作成するには、バイト配列
credential_id と、PublicKeyCredentialParameters
のリスト
allowed_algorithms が与えられたとして、その
COSEAlgorithmIdentifier
を伴う鍵ペアのタプルを返します:
注: Credential ID に対して既存の関連付けられた鍵ペアを見つけるか、 新しい関連付けられた鍵ペアを作成し、その鍵ペアをアルゴリズムとともに返します。
-
browser_bound_map[credential_id] が存在する場合
-
bbk_id を browser_bound_map[credential_id] とします。
-
bbk_and_algorithm を keypair_map[bbk_id] とします。
-
-
browser_bound_map[credential_id] が存在しない場合
-
(new_bbk_and_algorithm, bbk_id) を、 allowed_algorithms を使用して鍵ペアを 作成する結果とします。
-
binding_result を、bbk_id と credential_id を使用して 鍵ペアをバインドする結果とします。結果が失敗の場合、 bbk_and_algorithm を null とします。
-
binding_result が失敗でない場合、bbk_and_algorithm を new_bbk_and_algorithm とします。
-
-
bbk_and_algorithm を返します。
6.4. ブラウザバウンド公開鍵の取得
ブラウザバウンド公開鍵を取得する手順は、鍵ペアと COSEAlgorithmIdentifier
のタプル bbk_and_algorithm を与えられ、バイト配列を返すものです:
注: ブラウザバウンド鍵 の 公開鍵 をエンコードして取得します。
-
bbk を bbk_and_algorithm[0] とする。
-
algorithm を bbk_and_algorithm[1] とする。
-
public_key を、algorithm に対応する既定手順に従って取得した bbk の 公開鍵 とする。
-
encoded_public_key を public_key の COSE_Key エンコードとする。WebAuthn の credentialPublicKey を参照してください(WebAuthn § 6.5.1 Attested Credential Data)。
-
encoded_public_key を返す。
6.5. クライアントデータの署名
指定された鍵ペアと COSEAlgorithmIdentifier
のタプル bbk_and_algorithm とバイト配列 client_data_json を与えられ、バイト配列を返すことで ブラウザバウンド署名を生成する手順を実行します:
注: CollectedClientData
(CollectedClientAdditionalPaymentData
または
CollectedClientAdditionalPaymentRegistrationData
を含む)に対して、browser bound
key の 秘密鍵 を用いて署名を行います。
-
bbk を bbk_and_algorithm[0] とする。
-
algorithm を bbk_and_algorithm[1] とする。
-
signature を、bbk の 秘密鍵 を用いて algorithm に従い client_data_json に対して生成した結果とする。アルゴリズムの詳細は IANA COSE Algorithms レジストリ [IANA-COSE-ALGS-REG] を参照してください。
注: 結果は client_data_json に対する暗号署名であり、bbk の 秘密鍵 を使っています。
-
signature を返す。
7. 共通データ構造
以下のデータ構造は登録と認証の間で共有されます。
7.1. PaymentCredentialInstrument
辞書
dictionary PaymentCredentialInstrument {required USVString ;displayName required USVString ;icon boolean =iconMustBeShown true ;USVString ; };details
The PaymentCredentialInstrument
dictionary contains the information to be
displayed to the user and signed together with the transaction details. It
contains the following members:
displayName-
ユーザーに表示される支払い手段の名前。
注:
displayNameの 国際化についての議論は、 § 14 国際化に関する考慮事項を参照してください。 icon-
支払い手段のアイコンの URL。
注:
iconURL は、インターネットからアクセス可能なサーバー上の画像 (例:https://bank.example/card.png)を識別することも、 Data URL [RFC2397] を介してアイコンデータを直接エンコードすることもできます。 これら 2 種類の URL のうち、Data URL は リライングパーティにいくつかの利点を提供します。信頼性を向上できます(たとえば、 アイコンをホストするサーバーが利用できない場合など)。 また、リライングパーティは、ブラウザーがユーザーに表示したものについての 暗号学的証拠を持つため、検証も強化できます。アイコン URL はCollectedClientAdditionalPaymentData構造の一部として署名されます。注: 関連するアクセシビリティに関する考慮事項を参照してください。
iconMustBeShown-
要求が成功するために、指定されたアイコンが正常に取得され表示されなければならないかどうかを示します。
details-
ユーザーに表示される、支払い手段に関する任意の追加詳細文字列。
注:
detailsの 国際化についての議論は、 § 14 国際化に関する考慮事項を参照してください。
7.2.
PaymentEntityLogo 辞書
dictionary PaymentEntityLogo {required USVString ;url required USVString ; };label
PaymentEntityLogo
dictionary は、現在の取引を円滑に進める支払いエンティティの
ロゴを説明する情報を含みます。これには次のメンバーが含まれます:
url-
ロゴの URL。
注:
urlは、インターネットからアクセス可能なサーバー上の画像 (例:https://bank.com/logo.png)を識別することも、 Data URL [RFC2397] を介してロゴデータを直接エンコードすることもできます。 これら 2 種類の URL のうち、Data URL は リライングパーティにいくつかの利点を提供します。信頼性を向上できます(たとえば、 ロゴをホストするサーバーが利用できない場合など)。 また、リライングパーティは、ブラウザーがユーザーに表示したものについての 暗号学的証拠を持つため、検証も強化できます。ロゴ URL はCollectedClientAdditionalPaymentData構造の一部として署名されます。 label-
ロゴの説明ラベル。ユーザーエージェントは、このラベルをユーザーに表示してもよい (ただし必須ではありません)(§ 4.10 取引確認 UX の表示を参照)。 また、アクセシビリティ目的で使用するべきです (たとえば、UX 上でこのロゴを説明するときにスクリーンリーダーによって読み上げられるようにするため)。
8. Permissions Policy の統合
この仕様は "payment"
ポリシー識別子文字列を [payment-request] から使用して、SPC 認証へのアクセスを制御します。これは PaymentRequest
コンストラクタに従います。
この仕様の以前のバージョンとの後方互換性のために、Credential Management
Credential Type Registry は、タイプ public-key の代替の Create Permissions Policy として "payment" ポリシー識別子文字列を追加するよう拡張されています。将来のバージョンではこの振る舞いが完全に非推奨になる可能性があります。
注: アルゴリズムは [CREDENTIAL-MANAGEMENT-1] に指定されている通り、実際の permissions policy
評価を行います。これは、ポリシー評価が current settings object へのアクセスがあるときに発生する必要があるからです。[[Create]](origin, options, sameOriginWithAncestors)
および [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
の 内部メソッド は、そのようなアクセスを持ちません。なぜならそれらは 並列に呼び出されるからであり([CREDENTIAL-MANAGEMENT-1]
に指定されたアルゴリズムによって)、この評価はそこで行われないためです。
9. SPC Relying Party の操作
9.1. 認証アサーションの検証
Secure Payment Confirmation の認証セレモニーを実行するために、 リライングパーティは、次のように進めなければなりません:
-
credential を、SPC caller による Secure Payment Confirmation 支払い ハンドラーの呼び出しが成功して返された
PublicKeyCredentialとします。注: SPC は加盟店による 認証制御を可能にするよう設計されているため、SPC を呼び出すエンティティは リライングパーティでない場合があります。この最初の手順は、SPC caller が SPC を介して取得したクレデンシャルをリライング パーティに返したことを前提としています。
-
次の変更を加えて、WebAuthn で 指定されている 手順 3〜21を実行します:
-
手順 5 では、credential.
idが、リライングパーティによって SPC caller に提供された 公開鍵クレデンシャルのいずれかを識別することを検証します。 -
手順 11 では、C["
type"] の値が文字列payment.getであることを検証します。 -
手順 12 では、C["
challenge"] の値が、リライングパーティによって SPC caller に提供されたチャレンジの base64url エンコードと等しいことを検証します。 -
手順 13 では、C["
origin"] の値が、リライングパーティが SPC の呼び出し元として期待する オリジンと一致することを検証します。 -
手順 13 の後に、次の手順を挿入します:
-
C["
payment"]["topOrigin"] の値が、リライングパーティが期待するトップレベルオリジンと一致することを検証します。 -
C["
payment"]["payeeName"] の値が、ユーザーに表示されるべきだった受取人の名前がある場合、その名前と一致することを検証します。 -
C["
payment"]["payeeOrigin"] の値が、ユーザーに表示されるべきだった受取人のオリジンがある場合、そのオリジンと一致することを検証します。 -
C["
payment"]["paymentEntitiesLogos"] の値が、ユーザーに表示されるべきだったロゴがある場合、そのロゴの厳密かつ順序付きの部分集合であることを検証します。注: ユーザーエージェントは、 すべてのロゴを表示しないことが許可されていますが、ユーザーに表示されなかったロゴを
CollectedClientAdditionalPaymentDataに含めてはなりません。 -
C["
payment"]["instrument"] の値が、ユーザーに表示されるべきだった支払い手段の詳細と一致することを検証します。
-
10. ユーザーエージェントの自動化
ユーザーエージェントの自動化とウェブサイトのテストの目的のために、本書は以下の [WebDriver2] の 拡張コマンド を定義します。関係者はまた 同等の自動化セクション を [webauthn-3] でも参照すべきです。
10.1. Set SPC Transaction Mode
The Set SPC Transaction Mode WebDriver 拡張コマンド は、ユーザーエージェントに対して Secure Payment Confirmation を、自動的にユーザーがトランザクション確認 UX を承認または拒否するようにシミュレートするモードに設定するよう指示します。
The current transaction automation mode は、SPC
に対して現在有効な自動化モードを追跡します。デフォルトは "none" です。
| HTTP Method | URI Template |
|---|---|
| POST | /session/{session id}/secure-payment-confirmation/set-mode
|
The remote end steps are:
-
もし parameters が JSON の Object でない場合、WebDriver エラー を WebDriver エラーコード invalid argument で返してください。
-
mode を プロパティを取得する 操作で
"mode"という名前のプロパティを parameters から取得した結果として得てください。 -
もし mode が undefined または "
autoAccept"、"autoChooseToAuthAnotherWay"、"autoReject"、"autoOptOut" のいずれでもない場合、WebDriver エラー を WebDriver エラーコード invalid argument で返してください。 -
current transaction automation mode を mode に設定してください。
-
success をデータ
nullと共に返してください。
11. セキュリティに関する考慮事項
この仕様は WebAuthn の上に構築されているため、WebAuthn のセキュリティ考慮事項 が適用されます。以下の節は、Secure Payment Confirmation 固有のセキュリティ考慮事項であり、この仕様が WebAuthn からどのように逸脱するかを示します。
11.1. クロスオリジン認証手続き
Secure Payment Confirmation が WebAuthn と大きく異なる点は、 サードパーティが、別のリライングパーティのクレデンシャルを使用して 認証セレモニーを開始し、そのアサーションを サードパーティへ返すことを許可している点です。この機能により、リライングパーティは ログイン攻撃と 支払い攻撃の両方にさらされる可能性があり、ここでそれらについて説明します。
11.1.1. ログイン攻撃
Secure Payment Confirmation 用に作成されたクレデンシャルは有効な WebAuthn クレデンシャルであるため、リライングパーティは、 特定のユーザーについて、ログインと支払いの両方に同じ クレデンシャルを使用したいと考える場合があります。受け取ったアサーションを慎重に検証しない場合、 これにより、リライングパーティのログインシステムに対する攻撃が可能になります。
攻撃は次のとおりです:
-
ユーザーは、加盟店サイトである、または加盟店サイトを装う
attacker.exampleを訪問します。 -
attacker.exampleは、relyingparty.exampleからユーザーのクレデンシャルを取得します。 これは正当に行われる場合もあれば、relyingparty.exampleまたはrelyingparty.exampleがクレデンシャルを共有していた別の 当事者から盗むことによって行われる場合もあります。 -
attacker.exampleは SPC 認証を開始し、ユーザーは 取引(それが正当である場合もそうでない場合もあります)に同意します。 -
attacker.exampleは API 呼び出しから受け取った支払いアサーションを取得し、たとえばhttps://relyingparty.example/loginへ POST を送信することで、relyingparty.exampleのログインエンドポイントへ送信します。 -
relyingparty.exampleは欠陥のあるアサーション検証コードを使用しており、 署名は確認するものの、必要なフィールド(下記参照)の検証に失敗し、 そのログイン試行を正当なものと信じます。 -
relyingparty.exampleは、たとえばログイン Cookie をattacker.exampleに返します。relyingparty.exampleにあるユーザーのアカウントは、これで侵害されたことになります。
リライングパーティは、この攻撃に対して 2 つの方法で防御できます。
第一に、リライングパーティは、必要に応じて WebAuthn ログインまたは SPC 支払いについて、常に正しいアサーション 検証手順に従わなければなりません。特に、次のフィールドはいずれも、クレデンシャルの不適切な使用を 検出するために使用できます:
-
CollectedClientData["type"]- ログインでは "webauthn.get"、SPC では "payment.get"。 -
CollectedClientData["challenge"] - この値は、WebAuthn または SPC のいずれかを呼び出す前に、 リライングパーティサーバーからサイトへ提供されるべきであり、期待される、 適切な、以前に提供された値と一致することを検証するべきです。 -
CollectedClientData["origin"] - SPC がクロスオリジンで実行されている場合、この値には呼び出し元のオリジン (上記の例ではattacker.exampleなど)が含まれます。
第二に、リライングパーティは、支払い用クレデンシャルとログイン用
クレデンシャルを分離して保持することを検討できます。これを行う場合、リライングパーティは、
Secure Payment Confirmation 用のクレデンシャルをサブドメイン(例:
https//payment.relyingparty.example)でのみ登録し、支払い用クレデンシャルと
ログイン用クレデンシャルをデータベース内で分離して保持するべきです。
payment
拡張機能を用いて作成されたクレデンシャルのみです。仕様は将来、
それを反映するよう更新される可能性があります。
現在の実装と仕様の両方において、payment
を用いて作成されたクレデンシャルは、リライングパーティが望む場合、
ログインに使用できます。これは変更されるとは予想されていません。
11.1.2. 支払い攻撃
Secure Payment Confirmation のアサーションは、進行中のオンライン取引の一部でない限り、 基本的に役に立ちません。
悪意あるサードパーティが、ユーザーアカウントを乗っ取ろうとする代わりに、 Secure Payment Confirmation クレデンシャル(正当に取得したかどうかを問わない)を使用して 不正な支払いを開始する攻撃に対しては、さまざまな仕組みが防御します:
-
攻撃者が SPC を開始すると、ユーザーエージェントによって、取引詳細 (受取人と金額を含む)を明確に示す UI がユーザーに表示されます。このシナリオでは、 ユーザーは「キャンセル」する可能性が非常に高いです。
-
ユーザーがその取引に同意し、後続の WebAuthn 認証セレモニーを完了した場合、 攻撃者は、リライングパーティに対する署名済み SPC アサーションを持つことになります。
-
リライングパーティが取引を想定していない場合、その アサーションを拒否します。
-
リライングパーティが取引を想定している場合、少なくとも 次のいずれかを検出し、アサーションを拒否します:
-
攻撃者が有効な進行中の支払いと競争しようとする場合、不正な
CollectedClientData["challenge"]。 -
攻撃者がユーザーと有効な加盟店サイトの間に入り、アサーションを転送しようとする場合、 不正な
CollectedClientData["origin"]。
-
11.1.3. WebAuthn 拡張機能はリライング パーティにのみ許可される
WebAuthn では、認証拡張機能を認証セレモニー中に使用できます。 一部の拡張機能は、リライングパーティにとって 機微なデータを(認証器上に)格納または取得するために使用できます。
Secure Payment Confirmation 認証セレモニーでは、サードパーティ(呼び出し元)が、 別のリライングパーティに所有されるクレデンシャルについて セレモニーを開始できます。呼び出し元が任意の WebAuthn 拡張機能を指定できる場合、その呼び出し元は、リライングパーティが呼び出し元と共有する意図のなかった、 リライングパーティに属する 機微なデータにアクセスできる可能性があります。
たとえば、largeBlob 拡張機能は、大量のデータの格納と取得を可能にします。
攻撃者が largeBlob 拡張機能を使用して SPC セレモニーを開始できる場合、
ユーザーがそのセレモニーを承認することを前提として、リライングパーティが
そこに格納していたデータを読み取れる可能性があります。
このリスクを軽減するため、Secure Payment Confirmation はクロスオリジン認証セレモニーでの WebAuthn 拡張機能の使用を禁止します。これらは、呼び出し元がリライングパーティである場合にのみ 許可されます。
11.2. マーチャント提供の認証データ
銀行は、受け取った認証アサーションを検証することで、 それが加盟店から提供された取引詳細と一致していることを確認し、 偽装から保護できますし、そうするべきです。
これは、この仕様のサードパーティ認証セレモニーの帰結として、 有効な取引(すなわち、 リライングパーティが想定している取引)であっても、 ユーザーに表示される取引詳細をサードパーティが提供するためです:
-
取引金額と通貨
-
支払い手段の名前とアイコン
-
受取人の名前とオリジン
これにより、加盟店がユーザーに誤ったデータを提示する偽装攻撃につながる可能性があります。 たとえば、加盟店は(バックエンドで)銀行に対して $100 の購入を開始していると伝えながら、SPC API には $1 を渡すことができます(したがって、ユーザーには検証対象として $1 の取引が表示されます)。 または、加盟店が正しい取引詳細を提供していても、リライングパーティが 想定するものと一致しない Secure Payment Confirmation クレデンシャルを渡す可能性があります。
Secure Payment Confirmation は実際には、この種の攻撃を防ぐことを、 現在の Web よりも容易にします。今日のオンライン決済では、銀行は 加盟店がチェックアウトフローでユーザーに正しい金額を表示したと 信頼しなければなりません(また、不正の発見はいずれも支払い後、 ユーザーが口座明細を確認したときになります)。
11.3. 攻撃者生成の Browser Bound Key
リライングパーティ(例: 銀行)は、認証 アサーションを検証することで、攻撃者が生成した BBK から保護できますし、そうするべきです。 このアサーションには BBK 公開鍵が含まれており、署名が無効なクリプトグラムからの BBK 公開鍵は無視します。署名は 2 つ存在しますが、1 つは SPC Credential からのもの、もう 1 つは BBK からのものです。 アサーションは、BBK に加えてパスキーを使用して検証するべきです。 BBK は追加の署名を提供するものであり、パスキー署名の 代替ではありません。
加盟店を装う攻撃者は、BBK 公開鍵を別のものに置き換えようとする可能性があります。 その場合、攻撃者は対応する秘密鍵を制御しています。後で、攻撃者はユーザーになりすまして 加盟店 Web サイトを訪問し、加盟店が SPC を呼び出したときに、攻撃者の 秘密鍵を使用して SPC クリプトグラムに署名します。攻撃者は BBK の デバイス紐付けの側面を破ったことになります。
しかし、この攻撃は実行可能ではありません:
-
攻撃者が BBK を置き換えている場合: リライング パーティは、パスキー公開鍵を使用して
CollectedClientData(BBK 公開鍵を含む)を検証する際に、不正な署名を検出します。リライング パーティは、この取引を拒否し、この BBK 公開鍵を 信頼されないものとして扱うべきです。 -
攻撃者がユーザーになりすまそうとする場合: リライング パーティは、 パスキー公開鍵を使用して検証する際に、不正な署名を検出します。リライングパーティは、この BBK 公開鍵を引き続き 信頼されないものとして扱うべきです。
11.4. ユーザーアクティベーション要件の欠如
ユーザーエージェントが§ 4.3 ユーザーアクティベーション要件の変更に記載されているようにユーザーアクティベーションを必要としない場合、追加のセキュリティ緩和策を検討する必要があります。ユーザーアクティベーションを要求しないと、ユーザーが直前にページに操作しなくても Secure Payment Confirmation の流れを開始できるため、スパムやクリックジャッキング攻撃のリスクが高まります。
スパム対策としては、ユーザーが現ページでユーザーアクティベーションなしで既に Secure Payment Confirmation フローを表示されている場合など、ある閾値以降でユーザーアクティベーション要件を強制することをユーザーエージェントが決定してもよいでしょう。クリックジャッキング対策としては、ダイアログ表示直後のクリックを一定時間無視するしきい値をユーザーエージェントが実装してもよいでしょう。
もう一つの関連する対策はPaymentRequest.show()にあり、
Payment Request API はドキュメントの可視性を要求するため、SPC はバックグラウンドタブや最小化ウィンドウ、その他の隠れた状況では発動できません。
12. プライバシーに関する考慮事項
この仕様は WebAuthn の上に構築されており、WebAuthn のプライバシーに関する考慮事項が適用されます。以下の小節は、Secure Payment Confirmation 固有のプライバシー考慮事項であり、この仕様が WebAuthn から逸脱する場合について記述しています。
12.1. 資格情報 ID を調査する試み
WebAuthn の認証 セレモニーのプライバシーに関するセクションに従い、Secure Payment Confirmation の実装者は、 悪意ある呼び出し元(現在ではリライングパーティでさえない場合があります)が、 次の場合を区別できないようにしなければなりません:
-
クレデンシャルが利用できない。
-
クレデンシャルは利用できるが、ユーザーがその使用に同意しない。
上記の場合を区別できると、悪意あるリライングパーティが、どの クレデンシャルが利用可能かを調べることで ユーザーを識別できる情報が漏洩します。
Secure Payment Confirmation では、常に
取引確認 UXを表示し、
SPC Credential が利用できない場合と、
SPC Credential は利用できるが
ユーザーがそれを使用しないことを選択した場合の
両方で、同じ返却エラー("NotAllowedError"
DOMException)を返すことで、
このリスクを軽減します。
12.2. 異なる支払い手段の紐付け
リライングパーティが、特定のユーザーについて 複数の支払い手段に同じクレデンシャルを使用する場合、加盟店は、通常なら結び付けられない可能性のある 支払い手段に関する情報を結合できるようになるかもしれません。つまり、ユーザー U が支払い手段 P1 および P2 を使って行う 2 つの異なる取引(同じ加盟店 M 上、または共謀する 2 つの加盟店 M1 と M2 上のいずれか)にわたって、 加盟店は、P1 と P2 が同じユーザーのものであることを知ることができるようになる可能性があります。
現在の多くのオンライン決済フローでは、これは重大な リスクではない場合があります。というのも、多くの場合、ユーザーはこの結合を行うのに十分な情報 (たとえば、名前、メールアドレス、配送先住所)を提供しているためです。
しかし、識別情報がより少ない支払い方法 (たとえば、トークン化)が一般的になる場合、エコシステムの関係者が ユーザーのプライバシーを保護するための措置を講じることが重要です。たとえば:
-
決済システムは、第三者によるクレデンシャル ID または BBK 公開鍵の保存に制限を設ける規則を確立する可能性があります。
-
リライングパーティが単一の SPC クレデンシャルに複数の手段を割り当てる場合、そのクレデンシャル ID を他の当事者と共有しないことを選択するかもしれません。この場合でも、リライングパーティは、その SPC クレデンシャル自体を (ファーストパーティまたはサードパーティのコンテキストのいずれでも)使用して、ユーザーを認証できます。
-
リライングパーティ(例: 銀行)は、ユーザーが 支払い手段ごとに別個の SPC クレデンシャルを登録できるようにするかもしれません。これによって、リライング パーティがそれらのアカウントを内部で結合することは防げません。
12.3. 資格情報 ID をトラッキングベクターとして利用するリスク
単一の支払い手段であっても、 リライングパーティから返されるクレデンシャル ID は、強力なクロスサイト識別子であるため、 悪意あるエンティティによってトラッキングベクトルとして使用される可能性があります。しかし、 それらをリライングパーティから取得するには、加盟店はすでに、それと同程度に強力な識別子を リライングパーティに渡す必要があります(例: クレジットカード番号)。
12.4. Browser Bound Key のトラッキングベクターとしてのリスク
BBK 公開鍵は、各 SPC 支払いアサーション時(および初回の第一者 SPC 資格情報生成時)にのみ返されます。ただし、マーチャントが SPC を開始して BBK を取得するには Relying Party から資格情報 ID を取得し、ユーザーがパスキーで取引を認証する必要があります。BBK 公開鍵へのアクセスにはまず資格情報 ID が必要となるため、BBK 公開鍵がトラッキングリスクを追加することはありません。
12.5. securePaymentConfirmationAvailability を利用したフィンガープリンティング
securePaymentConfirmationAvailability
API は、特定のフレームで Secure Payment Confirmation API
が利用できない理由を個別に返すため、フィンガープリンティングリスクがあります。これらの理由が重要な情報を漏洩するとは考えられていませんが、考慮しておくべきです:
-
unavailable-feature-not-enabled: ユーザーエージェントがどの条件で Secure Payment Confirmation の利用可否を切り替えるかによりフィンガープリンティングリスクがあります。ユーザーエージェントは、(もし仕様を実装するなら)すべてのユーザー、または特定の OS など十分大きなグループに提供することで追加のフィンガープリンティングが発生しないようにすべきです。例として、特定の OS の全ユーザーに Secure Payment Confirmation を提供し、他の OS では提供しないことなどが考えられます(この場合、UA文字列が既に提供している以上のフィンガープリントにはなりません)。 -
unavailable-no-permission-policy: 追加のフィンガープリンティングリスクはありません。既に "payment" パーミッションポリシーは、PaymentRequestオブジェクトを構築時に(パーミッションポリシーが有効でないときエラーになるため)既にサイレントに検出可能です。 -
unavailable-no-user-verifying-platform-authenticator: 既存のisUserVerifyingPlatformAuthenticatorAvailableAPI 以上のフィンガープリンティングリスクはありません。
上記以外にも、この仕様では、たとえ具体的な理由がわかっていても、ユーザーのプライバシー保護のために unavailable-unknown-reason
を返すことをユーザーエージェントに許可しています。たとえば、ユーザーエージェントが現在のフレームで他のフィンガープリントリスクを伴う API アクセスを検出している場合などに有効です。
12.6. getSecurePaymentConfirmationCapabilities によるフィンガープリント
getSecurePaymentConfirmationCapabilities
API は、ユーザーのデバイスが持つ機能(あるいは欠如している機能)に関する特定の情報をサイレントに返すことができるため、フィンガープリントのリスクをはらんでいる。
このリスクを軽減するために、ユーザーエージェントは、false という値を返すのではなく、返却されるレコードからキーを省略することを優先すべきである (SHOULD)。キーを省略すること(§ 4.7 Secure Payment Confirmation 機能の利用可能性
で説明されているように)の方が、ある機能が未サポートであると明示的に示す場合よりもフィンガープリント表面が小さくなる。ユーザーエージェントは、ユーザーのプライバシーを保護するため、サポートされている場合であっても、その機能を省略することを選択してもよい
(MAY)。
SecurePaymentConfirmationCapability
に列挙されている特定の機能についての考慮事項:
-
browserBoundKeyHardware: ユーザーのデバイスにハードウェアセキュリティチップがあることを明かすリスクがある。この情報は、[DBSC] など、他の Web API を通じてすでにサイレントに利用可能である場合もある。
12.7. ユーザーのオプトアウト
API オプション showOptOut
は、ユーザーエージェントに対し、ユーザーが Relying Party
による情報の保存からオプトアウトしたいことを示す手段を提供するよう指示する。ユーザーがこのオプトアウトを実行すると、ユーザーがオプトアウトの意図を持つことを示すために、呼び出し元へ OptOutError
が返される。その後、このオプトアウトに対してどのように対応するかは呼び出し元次第であり、例えばユーザー向けに保存されている支払情報を消去する、といった対応がありうる。
実装者は、OptOutError
が返されることによって、ユーザーが資格情報を持っているにもかかわらず認証を完了しなかったことが明らかにならないように注意しなければならない (must)。これは、§ 12.1 資格情報 ID のプロービング
と同様の手段で緩和できる。例えば、資格情報の一致が見つからなかった場合の中間的な UX においても、ユーザーにオプトアウトの機会を提供する、などである。
これはブラウザのデータや資格情報を削除するための仕組みとして意図されたものではなく、開発者がユーザーエージェント経由でオプトアウトを促すためのものである。ユーザーエージェントは、例えば次のような説明文を添えることで、この点をユーザーに明確にすべきである:「このプロバイダーは、あなたの支払方法に関する情報を保存している場合があります。削除をリクエストすることができます。」
13. アクセシビリティに関する考慮事項
ユーザーエージェントは icon
および displayName
を組み合わせてレンダリングします。Relying Party は displayName
で十分な情報を提供することでアイコン表示のアクセシビリティを確保します(例:アイコンが銀行なら銀行名も displayName
に含めるなど)。
この仕様を実装するユーザーエージェントは、WebAuthn のアクセシビリティに関する考慮事項と、PaymentRequest のアクセシビリティに関する考慮事項の両方に従うべきです。
14. 国際化に関する考慮事項
API の呼び出し元は、取引ダイアログの希望ロケールや表示文字列のローカライズ言語を locale
メンバーで指定すべきです。一般的にはこのメンバーはリクエスト元ページのローカライズと一致させるべきです(たとえば、リクエストをトリガーするボタンの lang 属性を参照するなど)。
この仕様は、呼び出し元が API に提供する各表示文字列(例:displayNameなど)に言語や方向性メタデータを付加する仕組みは(まだ)含んでいません。
その間、API 呼び出し元は:
-
locale(指定する場合)と言語付き表示文字列の値との間の一貫性を意識してください。 -
文字列内に方向転換が含まれる場合には、表示時に正しくレンダリングされるようにしてください(参考:双方向テキスト用 Unicode 制御文字の使い方や 基底方向のインライン変更)。
実装(および表示処理)は、表示用文字列値をユーザーインターフェイスに挿入する際、bidi isolation を適用し、方向がわかれば指定し、分からない場合は first-strong("auto")をデフォルトとすべきです。
15. IANA に関する考慮事項
この節は 拡張識別子 を IANA "WebAuthn Extension Identifiers" レジストリ [IANA-WebAuthn-Registries] に追加します([RFC8809] による)。
-
WebAuthn Extension Identifier: payment
-
説明: この拡張は Secure Payment Confirmation API で定義される次の機能をサポートします:(1)クロスオリジン iframe での資格情報作成(2)Relying Party 以外の第三者が Relying Party の代わりに認証式を実施できること(3)ブラウザによる Secure Payment Confirmation 資格情報の識別とキャッシュ。SPC が WebAuthentication と大きく異なる重要な点については、特に § 11 セキュリティに関する考慮事項 と § 12 プライバシーに関する考慮事項 を参照
-
仕様書: 本仕様書 § 5 WebAuthn Extension - "payment" 節
-
備考: 登録は Web Authentication Working Group との 2023年5月3日討議に準拠