OpenID4VP検証者ガイド:EUDIウォレットの受け入れ
EUDIウォレット向けOpenID4VP検証者の仕組みを解説します。リクエストオブジェクト、DCQLクエリ、レスポンスモード、SD-JWT VCとmdocの検証、EU法におけるHAIPのルール、よくある誤り、テスト環境を取り上げます。

要点
OpenID4VP(OpenID for Verifiable Presentations)は、検証者がデジタルウォレットにクレデンシャルを要求し、署名付きのプレゼンテーションを受け取るためのプロトコルです。バージョン1.0は2025年7月10日にOpenID Final Specificationとなり、EUデジタルアイデンティティ(EUDI)ウォレットはリモート提示にこれを使用します。[2][3]
- DCQLクエリを含む署名付きリクエストを送信すると、ウォレットがVP Tokenを返します。
- 発行者の署名、開示情報(disclosures)、キーバインディング、失効状態は自社で検証します。
- EUDIウォレットについては、EU法が証明書と登録に関するルールを追加しています。
OpenID4VPは、ウェブサイトやアプリがウォレットに対し、氏名や生年月日など、ある人物に関する事項の証明を求める仕組みです。検証者は必要なクレデンシャルとクレームを指定し、ユーザーがウォレットで承認すると、ウォレットはプレゼンテーションを返します。検証者はそれを暗号技術で検証します。仕様自体の表現では、OpenID4VPは「クレデンシャルを要求し提示するためのプロトコルを定義する」ものです。[1]
本ガイドは、EUDIウォレット向けのOpenID4VP検証者を構築する開発者を対象としています。リクエストオブジェクト、DCQL、レスポンスモード、デバイスフロー、SD-JWT VCとmdocの検証、EU法におけるHAIPのルール、よくある誤り、テストできる場所を扱います。
OpenID4VPをわかりやすく
OpenID4VPは、OAuth 2.0の認可リクエストの形式を再利用します。検証者はレスポンスタイプvp_tokenを要求し、成功したレスポンスにはプレゼンテーションを格納したvp_tokenパラメータを含める必要があります。[1] 交換するコードやアクセストークンはありません。データはレスポンスの中で届きます。
ウォレットは依拠当事者を認証し、登録した範囲を超える要求をしていないかを確認し、ユーザーの承認を得てプレゼンテーションに署名します。その後、依拠当事者が発行者の署名、失効状態、デバイスバインディングを検証します。[3] 本人識別データ(PID)はSD-JWT VCとISO/IEC mdocの2つの形式で発行され、いずれもソルト付きハッシュを使用するため、ユーザーは一部の属性を共有し、残りを秘匿できます。[5][3]
- 2025年7月10日最終仕様OpenID4VP 1.0が承認。
- 2026年7月22日公布CIR 2026/1731(2026年7月15日採択)が官報に掲載。
- 2026年7月23日ARF v3.0.0現行のアーキテクチャリリース。
- 2026年12月24日ウォレット各加盟国で少なくとも1つ。
- 2027年12月24日受け入れ規制対象の民間依拠当事者。
最終仕様から民間部門の受け入れ期日まで。[2][3][4][5]
OpenID4VP検証者のやり取りの流れ
OpenID4VPは、レスポンスモードdirect_postの参照設計を公開しています。このモードでは、ウォレットはレスポンスをブラウザ経由で送るのではなく、サーバーのエンドポイントにPOSTします。[1]
ウォレットが検証者を確認し、ユーザーが同意
OpenID4VP 1.0 第13.3節のdirect_post参照設計(簡略版)。[1]
- リクエストごとに「少なくとも16バイトの新しい暗号論的乱数」のnonceを生成します。
- レスポンスエンドポイントから受け取ったrequest-idを
stateとしてウォレットに送ります。 - ウォレットがPOSTしたら、新しい
response_codeを付けたリダイレクトURIを返します。 - transaction-idとそのコードでVP Tokenを取得し、nonceを確認します。
response_codeはセッション固定攻撃を防ぎます。これは、攻撃者があなたのリクエストを被害者のウォレットに中継する攻撃です。仕様は、クロスデバイスの場合には効果がないと注記し、その場合は追加の仕組みを推奨しています。[1]
動画準備中: flow-eudi-openid4vp
EUDIウォレットからのOpenID4VPプレゼンテーションの全工程。
OpenID4VPのリクエストオブジェクトとクライアント識別子
client_idはClient Identifier Prefixで始まります。これにより、ウォレットは検証者の認証方法を判断します。[1] サイズの大きいリクエストは参照渡しで送られます。ウォレットは署名付きリクエストオブジェクトをrequest_uriから取得します。QRコードの場合、リクエストが「QRコードに収まらない可能性がある」ため、仕様はrequest_uriを伴うdirect_postを推奨しています。[1]
| プレフィックス | ウォレットによる検証者の認証方法 | 署名付きリクエスト |
|---|---|---|
redirect_uri | 識別子はリダイレクトURIまたはレスポンスURI | 署名不可 |
x509_san_dns | リーフ証明書のSANに含まれるDNS名 | 必須 |
x509_hash | リーフ証明書のSHA-256ハッシュ | 必須 |
decentralized_identifier | DIDドキュメントの鍵 | 必須 |
verifier_attestation | ウォレットが信頼する発行者によるアテステーションJWT | 必須 |
openid_federation | フェデレーションのトラストチェーン | OpenID Federationに従う |
クライアント識別子プレフィックス、OpenID4VP 1.0 セクション5.9。[1]
EUDIの検証者の場合、使用するプレフィックスはEU法が定めています。リーフ証明書は「x509_hash クライアント識別子プレフィックスで使用するものとして、ETSI TS 119 475 に定めるRPアクセス証明書でなければならない」とされ、verifier_info の要素の1つは「登録証明書を含まなければならない」とされています。[5]
DCQLクエリ: 登録した内容だけを要求する
Digital Credentials Query Language(DCQL)は、要求するクレデンシャルとクレームを指定するJSONクエリです。必須の credentials 配列と、任意の credential_sets 配列を持ちます。各クレデンシャルクエリには id、format、meta オブジェクトが必要です。[1] 仕様に記載されたSD-JWT VCの例は次のとおりです。[1]
{ "credentials": [ { "id": "my_credential", "format": "dc+sd-jwt", "meta": { "vct_values": [ "https://credentials.example.com/identity_credential" ] }, "claims": [ {"path": ["last_name"]}, {"path": ["first_name"]}, {"path": ["address", "street_address"]} ] } ] }
mdocの場合、formatは mso_mdoc で、meta には doctype_value が入ります。[1] PIDの場合は、そのタイプとクレーム名に置き換えます。PIDの必須属性は、姓、名、生年月日、出生地、国籍です。[7]
require_cryptographic_holder_bindingのデフォルト値はtrueです。この設定は維持してください。これによりウォレットはキーバインディング証明を返します。[1]trusted_authoritiesは、ウォレットが提示する候補を絞り込むだけです。検証者は「受け取ったプレゼンテーションの発行者が信頼できることを自ら検証しなければならない」とされています。[1]- 依拠当事者は、登録した内容「以外のデータの提供を利用者に求めてはならない」とされており、ウォレットがこれを確認します。[4][3]
OpenID4VPのレスポンスモード
レスポンスモードは、VP Tokenをどのように返送するかを決めます。vp_token のデフォルトは fragment で、リダイレクトURIのフラグメントで返されます。[1]
| レスポンスモード | VP Tokenの送信先 | 暗号化 |
|---|---|---|
fragment | ブラウザ経由で、リダイレクトURIのフラグメントへ | いいえ |
direct_post | response_uri へのHTTP POST | いいえ |
direct_post.jwt | 暗号化されたJWTのHTTP POST | はい |
dc_api | Digital Credentials API経由で返送 | いいえ |
dc_api.jwt | 同上、暗号化あり | はい |
OpenID4VP 1.0のレスポンスモード。[1]
direct_postを使う場合、response_uriは必須で、redirect_uriは含めてはなりません。含めた場合、ウォレットはinvalid_requestを返します。[1] たとえばモルドバのEVO Walletは、同一デバイスのフローでdirect_post.jwtを用いるOpenID4VP 1.0、OpenID4VC HAIP 1.0に従ってプロファイルされたISO/IEC 18013-5 mdoc、失効管理のためのIETF Token Status Listを文書化しています。[11]
同一デバイス、クロスデバイス、Digital Credentials API
ARFは、サポートされるリモートの組み合わせとして次の3つを挙げています。リダイレクトとカスタムURIスキームに基づく伝送メカニズムと組み合わせたOpenID4VP、W3C Digital Credentials APIと組み合わせたOpenID4VPまたはISO/IEC 18013-7、そしてオプションとして、リダイレクトとカスタムURIスキームを用いたISO/IEC 18013-7です。[3]
同一デバイス
カスタムURIスキーム
- ブラウザがopenid4vp://をオペレーティングシステムに渡す
- 同じスマートフォンでウォレットが開く
ARF 4.4.3.1
クロスデバイス
QRコード
- デスクトップにスキャン用のQRコードが表示される
- フィッシングやリレー攻撃を受けやすい
ARF 4.4.3.1
ブラウザAPI
Digital Credentials API
- ブラウザが検証済みのオリジンを渡す
- Chrome 141でデフォルトで有効
OpenID4VP 付録A
ウォレットがOpenID4VPリクエストを受け取る3つの方法。[3][1][10]
ARFは、カスタムURIスキームは「クロスデバイスのフローには推奨されない」としており、代替手段としてDigital Credentials APIを挙げています。[3] このAPIを通じて、ウォレットはブラウザによって認証された検証者のオリジンを知ることができます。これは「フィッシング耐性にとって重要」です。[1] W3Cの仕様はまだドラフト段階です。[9] スマートフォンでユーザーに表示される内容は次のとおりです。
本人確認を行ってください
このウェブサイトがあなたのウォレットに情報を求めています。
1ブラウザがopenid4vp:// URIをオペレーティングシステムに送信します。[3]
リクエストを確認中
ウォレットが開き、依拠当事者に接続します。
2ウォレットが依拠当事者を認証し、その登録内容を確認します。[3]
共有する情報を選択
- 姓共有
- 生年月日共有
- 住所非共有
共有する
3ユーザーが属性を承認します。[3]
情報を受信しました
4ウォレットが送信し、ユーザーを元の画面に戻します。[1]
SD-JWT VCプレゼンテーションの検証手順
SD-JWT VCプレゼンテーションには、発行者が署名したJWT、ユーザーが開示したディスクロージャ、Key Binding JWTが含まれます。検証者は「個々のVerifiable Presentationをすべて検証しなければならない(MUST)」とされ、nonceが一致しないものは拒否します。[1]
1発行者署名を検証する
鍵が信頼されたPIDプロバイダーまたは属性証明プロバイダーまでチェーンでつながること。
2すべてのディスクロージャを確認する
各ディスクロージャのハッシュが、署名済みペイロード内のダイジェストと一致すること。
3Key Binding JWTを検証する
保有者の鍵による署名があり、nonceとaudienceが一致すること。
4失効を確認する
発行者のステータスリストを参照する。
すべての確認に合格
開示された属性を利用する
拒否し、別の手段を提示する
1件のSD-JWT VCプレゼンテーションに対する検証者の確認事項。[1][3]
発行者署名。ARFは、依拠当事者が行う確認の最初にこれを挙げています。トラストアンカーは、トラステッドリスト(ETSI TS 119 612)および信頼済みエンティティリスト(ETSI TS 119 602)から取得します。[3]
ディスクロージャ。署名済みペイロードにはダイジェストの_sd配列が含まれます。各ディスクロージャはソルト、クレーム名、値で構成されます。例:["eluV5Og3gSNII8EYnsxA_A", "family_name", "Doe"]。[1]各ディスクロージャをハッシュ化し、対応するダイジェストを探します。一致しない場合、発行者はそのディスクロージャに署名していません。
Key Binding JWT。保有者バインディングが求められる場合、ウォレットは「Key Binding JWT付きのSD-JWTを返さなければならない(MUST)」とされています。そのnonceはリクエストのnonceと、audはClient Identifierと一致しなければなりません。Digital Credentials APIを使う場合は、origin:を前に付けたオリジンと一致する必要があります。[1]仕様書の例は次のとおりです。
{ "nonce": "n-0S6_WzA2Mj", "aud": "x509_san_dns:client.example.org", "iat": 1709838604, "sd_hash": "Dy-RYwZfaaoC3inJbLslgPvMp09bH-clYP_3qbRqtW4" }
失効。依拠当事者は、プロバイダーが「PIDまたは属性証明を失効させていない」ことを確認します。[3]一例として、モルドバのEVO Walletは、この目的でIETF Token Status Listを使用することを文書化しています。[11]
注記
PIDの顔写真が必須となるのは2028年8月11日からです。それ以前にウォレットの顔写真との顔照合を計画しないでください。[5]
ISO/IEC 18013-7によるmdocの提示の概要
mdocの場合、VP Tokenには、ISO/IEC 18013-5のbase64urlエンコードされたDeviceResponseが格納されます。これは「SessionTranscriptに対する署名またはMACを含む」もので、OpenID4VPのハンドオーバー構造も含みます。[1] nonceとaudienceがSD-JWT VCをリクエストに結び付けるのと同じように、このハンドオーバーがmdocをリクエストに結び付けます。
注意
EU法は、Digital Credentials APIを介したmdocについて「ISO/IEC 18013-7:2025の附属書C」を適用します。[5] ISOでは、18013-7の2024年版は廃止され、後継版に置き換えられたものとして掲載されています。そのため、使用するライブラリがどの版を実装しているか確認してください。[8]
SD-JWT VCとmdocの比較では、それぞれの形式が適する場面を解説しています。
HAIPプロファイルがEUDIの検証者に追加する要件
High Assurance Interoperability Profile(HAIP)は、OpenID4VPの選択肢を絞り込みます。ARFは発行についてすでにHAIPを必須としており、その使用は「相互運用性を確保するために必要」としています。[3] 提示については、CIR 2026/1731が「OpenID4VC-HAIPプロファイル」と「ISO/IEC-mdocプロファイル」を定めています。[5]
| 要件 | 検証者としての対応 | 出典 |
|---|---|---|
| アクセス証明書 | x509_hashのRPアクセス証明書(ETSI TS 119 475)で署名する | CIR 2026/1731[5] |
| 登録証明書 | verifier_infoに含める | CIR 2026/1731[5] |
| 登録 | 設立地で登録する | eIDAS 第5b条(1)[4] |
| ウォレットによる確認 | ウォレットユニットが登録証明書を検証するのは2028年8月11日から。登録の期限ではない | CIR 2026/1731[5] |
登録証明書は「依拠当事者の利用目的を記述し、登録された属性を示す」ものです。登録に関する規則は2026年12月24日から適用されます。[6] 2028年8月11日という日付は、ウォレット側でのこの証明書の確認だけを対象とし、登録は対象外です。[5] ドイツは次のように要約しています。組織は「組織とユースケースについてアクセス証明書と登録証明書を受け取る」。[12] 登録の詳細はEUDIウォレットの依拠当事者ガイドで解説しています。
OpenID4VP検証者の構築でよくある間違い
| 間違い | 対処法 |
|---|---|
| nonceの再利用、または短いnonce | リクエストごとに新たなランダムバイトを16バイト以上使う[1] |
| audienceを検証しない | audをClient Identifierまたはオリジンと照合します[1] |
| 登録していないデータを要求する | DCQLクエリは登録内容に基づいて作成します[4] |
| デバイスをまたぐカスタムURIのQRコード | Digital Credentials APIを優先します[3] |
trusted_authoritiesをそのまま信頼する | 発行者はトラストリストに照らして自社で検証します[1] |
| 失効確認を省略する | 毎回ステータスを確認します[3] |
redirect_uriプレフィックスで署名する | このプレフィックスでは署名できません。x509_hashを使います[1][5] |
ウォレットの利用も任意です。ウォレットを使わない人について、アクセスは「いかなる形でも制限され、または不利に扱われてはならない」とされています。そのため、自社の検証者は別の経路と併存させることになります。[4]
テスト用リソース
各国のウォレットでテストする前に、リファレンスソフトウェアと適合性テストから始めます。
- conformance.eudi.devで適合性テストを実行します。[3]
- docs.eudi.devでリファレンス実装のドキュメントを読みます。これはドキュメントであり、テストではありません。[3]
- モルドバ国立銀行のデモ用検証者とそのソースコードを確認します。[13]
- ブラウザ経由の経路に頼る前に、Digital Credentials APIのドラフトを確認します。[9]
テスト計画の前提となる日付については、2026年と2027年のEUDIウォレットの期限を参照してください。
DiditによるEUDIウォレット検証の支援
DiditでのEUDIウォレットの受け入れは近日対応予定です。EUDIウォレットのタイムラインに合わせてロードマップに入っており、現在お使いのものと同じワークフロー内で提供する予定です。それまでの間も、今すぐ本人をリモートで確認できます。
- 現在、DiditではデジタルIDウォレットを通じて5つの国のeIDが稼働しています。MitID、BankID Sweden、Finnish Trust Network、Smart-ID、Mobile-IDです。eID検証を参照してください。
- eIDを持たない人の場合、フローは本人確認書類の検証に切り替わり、NFCチップの読み取り、ライブネス検知、顔照合を国ごとの設定で行います。KYCチェック一式の費用は$0.33です。
- AMLスクリーニングは同じフロー内で$0.20で実行されます。
依拠当事者としての義務は引き続き貴社が負います。ウォレットのドキュメントに、国ごとにeIDを有効化する方法が示されています。
Diditが提供するもの
- 各国のeIDによるサインインと書類による経路を1つのワークフローで
- すべてのチェックの証跡
貴社に残るもの
- ウォレット依拠当事者としての登録
- オンボーディングの判断と貴社のポリシー
要点
- OpenID4VP 1.0は2025年7月10日からOpenIDの最終仕様です。
- 登録内容の範囲に限定したDCQLクエリと新しいnonceを送信します。
- 発行者の署名、すべての開示、Key Binding JWT、失効状況を検証します。
- EUDIの検証者は
x509_hashのRPアクセス証明書で署名します。 - 対象となる民間の依拠当事者は、2027年12月24日までにウォレットを受け入れます。
よくある質問
OpenID4VPとは何ですか?
OpenID for Verifiable Presentationsは、クレデンシャルを要求し提示するためのプロトコルです。ウォレットは署名済みのプレゼンテーションをVP Tokenで返します。交換する認可コードやアクセストークンはありません。バージョン1.0は2025年7月10日にOpenID Final Specificationとなりました。[1][2]
EUDIウォレットはOpenID4VPを使用しますか?
はい。リモート提示ではISO/IEC 18013-7と並んで使用します。EU法はOpenID4VC-HAIPプロファイルとISO/IEC-mdocプロファイルを定めています。[3][5]
DCQLとは何ですか?
Digital Credentials Query Languageは、検証者が求めるクレデンシャルとクレームを指定するJSONクエリです。ウォレットは一致するプレゼンテーションを返します。EUDIウォレットでは、登録した属性のみを要求してください。[1][4]
EUDIの検証者はどのレスポンスモードを使うべきですか?
サーバー側の検証者はdirect_postまたは暗号化されたdirect_post.jwtを使用します。Digital Credentials API経由では、モードはdc_apiとdc_api.jwtです。[1]
Key Binding JWTはどのように検証しますか?
クレデンシャルに紐付けられた鍵で署名を確認し、次にnonceとaudienceを貴社のリクエストと照合します。Digital Credentials API経由では、audienceは貴社のオリジンです。[1]
EUDIの検証者はどのクライアント識別子プレフィックスを使いますか?
x509_hashです。ETSI TS 119 475に準拠したRPアクセス証明書を使います。登録証明書はverifier_infoに入れます。[5]
デバイスをまたいでQRコードを使えますか?
使えます。ただしARFは、フィッシング攻撃やリレー攻撃のおそれがあるため、デバイスをまたぐカスタムURIスキームを推奨していません。代替としてDigital Credentials APIを挙げています。[3]
ウォレットの顔写真と顔照合できますか?
現時点では確実ではありません。顔写真がPIDの必須データになるのは2028年8月11日からです。[5]
OpenID4VPの検証者はどこでテストできますか?
conformance.eudi.devで適合性テストを実行し、docs.eudi.devでリファレンス実装のドキュメントを確認してください。モルドバ中央銀行も、ソースコード付きのデモ検証者を公開しています。[3][13]
出典
- OpenID for Verifiable Presentations 1.0、OpenID Foundation、最終仕様。
- OpenID for Verifiable Presentations 1.0 最終仕様の承認、OpenID Foundation、2025年7月10日。
- Architecture and Reference Framework v3.0.0、GitHub上のeu-digital-identity-wallet、2026年7月23日リリース。
- 規則(EU) 2024/1183(eIDAS 2)、EUR-Lex、2024年4月30日付官報。
- 欧州委員会実施規則(EU) 2026/1731、EUR-Lex、2026年7月22日付官報。
- ウォレット依拠当事者の登録に関する欧州委員会実施規則(EU) 2025/848、EUR-Lex、2025年5月7日付官報。
- 個人識別データに関する欧州委員会実施規則(EU) 2024/2977、EUR-Lex、2024年12月4日付官報。
- ISO/IEC 18013-7、ISO規格ページ。
- Digital Credentials、W3Cドラフト。
- Digital Credentials APIの提供開始、Chrome for Developers。
- EVO Wallet 開発者ガイド、モルドバ政府、egov4dev。
- EUDIウォレット FAQ、eudi-wallet.gov.de。
- BNM デモ検証者、モルドバ政府、egov4dev。
OpenID4VPは、EUDIウォレットの中で開発者が最も多く扱う部分です。これを前提に開発できるほど安定しています。Diditのウォレット受け入れへの取り組みはEUDIウォレットのソリューションページを、全体像はeIDAS 2の概要をご覧ください。