0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VerifiableCredential・VerifiablePresentation をやさしく理解する~「デジタル身分証」のしくみを実例コードと図解で一緒に読み解こう~

0
Posted at

はじめに

皆さんは VCVP という言葉を聞いたことがあるでしょうか?これらは W3C が標準化したデジタル認証の仕組み で、マイナンバーカードや卒業証明書、資格証明書などを"デジタルで安全に"扱うための技術です。

この記事を読むと…

  • VC・VP とは何か
  • 実際の JSON を見ながら構造を理解
  • DID・OIDC との組み合わせ方

まで順を追って理解できるはずです。


現実世界のアナロジーから考える

まず日常の「紙の証明書」で考えてみましょう。

証明書 発行者 証明内容 改ざん防止
運転免許証 政府(公安委員会) 運転できる ICチップ・印刷
大学卒業証明書 大学 卒業した 実印・割印
資格証明書 試験機関 合格した 認定印

VC・VP はこれをそのままデジタル化したものです。発行者(Issuer)・保持者(Holder)・検証者(Verifier) の3者が登場します。

🏛️ Issuer(発行者)
市区町村・大学・試験機関
──── VC 発行 ────▶ 🧑 Holder(保持者)
あなた(ウォレット保管)
──── VP 提示 ────▶ 🏢 Verifier(検証者)
銀行・病院・EC サイト

VC(Verifiable Credential)とは?

VC は「発行者が署名した、改ざん不可能なデジタル証明書」です。JSON-LD という形式で書かれており、以下の要素で構成されます。

フィールド 役割
@context W3C VC 標準への参照 URL
type ["VerifiableCredential", ...]
issuer 発行者の DID / URL
issuanceDate 発行日時(ISO 8601)
credentialSubject 証明される属性(名前・年齢など)
proof 発行者の電子署名(Ed25519 など)

実例:年齢確認 VC の JSON

// 市区町村が発行した「18歳以上」証明 VC
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1"
  ],
  "type": ["VerifiableCredential", "AgeVerificationCredential"],
  "issuer": "did:web:city.example.gov",
  "issuanceDate": "2024-01-15T00:00:00Z",
  "expirationDate": "2029-01-15T00:00:00Z",
  "credentialSubject": {
    "id": "did:key:z6Mk...",
    "isAdult": true,
    "verifiedAt": "2024-01-15"
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2024-01-15T09:00:00Z",
    "verificationMethod": "did:web:city.example.gov#key-1",
    "jws": "eyJhbGci..."
  }
}

proof フィールドに電子署名が入るため、内容を1文字でも書き換えると署名検証が失敗します。これが「Verifiable(検証可能)」の意味です。


VP(Verifiable Presentation)とは?

VP は「保持者が選んだ VC をまとめて提示するための封筒」です。1つ以上の VC を束ねて、保持者自身の署名を加えます。

なぜ VP が必要?

免許証を見せると生年月日も住所も氏名も全部バレますが、VP + 選択的開示(SD-JWT など)なら「18歳以上かどうか」だけを証明できます。プライバシーの最小化が実現できます。

実例:VP の JSON

// 保持者が「年齢だけ」提示する VP
{
  "@context": ["https://www.w3.org/2018/credentials/v1"],
  "type": ["VerifiablePresentation"],
  "holder": "did:key:z6Mk...",
  "verifiableCredential": [
    { /* 上の AgeVerificationCredential をそのまま埋め込む */ }
  ],
  "proof": {
    "type": "Ed25519Signature2020",
    "challenge": "abc123",
    "domain": "example-bar.com",
    "jws": "eyJhbGci..."
  }
}

challengedomain を入れることで「この VP は example-bar.com 向けに今回だけ作った」ことを証明でき、使い回し攻撃(リプレイ攻撃)を防げます。


DID(Decentralized Identifier)との関係

DID は VC の「発行者と保持者の識別子」として使われます。did:web:did:key: など複数のメソッドがあります。

── DID による VC 検証の全体像 ──
🏛️
Issuer
発行者
(市区町村など)
①VC発行
🧑
Holder
保持者
(ウォレット)
②VP提示
🏢
Verifier
検証者
(銀行・病院)
⬆ DID を持つ
did:web:city.gov
⬆ DID を持つ
did:key:z6Mk...
③DIDを解決して
公開鍵を取得・署名検証 ⬇
🌐 分散型台帳 / HTTPS / ブロックチェーン  (DID Document を格納・公開)
DID メソッド 解決先 特徴
did:web HTTPS サーバ上の JSON 既存インフラで導入しやすい。企業・政府向け
did:key 公開鍵そのものをエンコード ブロックチェーン不要。テスト・個人利用向け
did:ion Bitcoin ネットワーク上 Microsoft が推進。高い耐改ざん性
did:ethr Ethereum スマートコントラクト Web3 DApps との親和性が高い

DID Document の例

// did:web:city.example.gov を解決すると取得できる DID Document
{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:web:city.example.gov",
  "verificationMethod": [{
    "id": "did:web:city.example.gov#key-1",
    "type": "Ed25519VerificationKey2020",
    "controller": "did:web:city.example.gov",
    "publicKeyMultibase": "z6Mk..."
  }]
}

検証者は以下の流れで VC の真正性を確認します:

  1. VC の issuer DID を解決
  2. DID Document から公開鍵を取得
  3. proof.jws を公開鍵で検証

OIDC(OpenID Connect)との組み合わせ

VC/VP は単体でも使えますが、既存の認証システムである OIDC と組み合わせた OID4VC(OpenID for Verifiable Credentials) も急速に普及しています。

通常の OIDC では「Google や Microsoft などの IdP がユーザーを認証して ID Token を発行する」という中央集権的な構造です。OID4VC はこれを拡張し、ユーザー自身のウォレットが VC/VP を使って認証・属性証明できる仕組みを加えます。

── OID4VC の全体像(3プロトコルの関係) ──
🏛️
Issuer
発行機関
(自治体・大学)
OID4VCI
VC発行
📱
Wallet
保持者のウォレット
(VC 保管・VP 生成)
OID4VP
VP提示
🏢
RP / Verifier
検証者
(銀行・病院)
OID4VCI
機関→ウォレットへ VC を安全に届ける発行プロトコル
SIOPv2
ウォレット自身が IdP になり外部依存ゼロで認証
OID4VP
必要な属性だけ VP で提示し RP が検証・ログイン許可

Wallet と IdP の関係について
上図の Wallet は「VC を保管し VP を生成する」役割です。通常は IdP とイコールではありません。 SIOPv2 を使った場合に限り、Wallet 自身が Self-Issued OpenID Provider(IdP)として振る舞い、外部の Google や Microsoft などに依存せず認証を完結できます。SIOPv2 を使わない OID4VP 単体のフローでは、Wallet は VP を提示するだけで、IdP は別途存在するか不要な構成になります。

RP(Relying Party)とは?
OIDC の用語で、「ユーザーの認証を外部の IdP(Identity Provider)に委託するサービス」のことです。わかりやすく言うと「ログインさせたい側のアプリ・サイト」です。例えば「Google でログイン」ボタンを設置している EC サイトが RP、Google が IdP にあたります。OID4VP の文脈では、RP が VP を受け取って検証する Verifier の役割も兼ねます。

OID4VC の3つのプロトコル

OID4VC は目的別に3つのプロトコルで構成されています。


1. OID4VCI(OpenID for Verifiable Credential Issuance)― VC を発行する

Issuer(発行機関)がユーザーのウォレットに VC を安全に届けるためのプロトコルです。

[ユーザー/ウォレット]                    [Issuer(発行機関)]
       |                                          |
       |-- ① Credential Offer を受け取る -------->|
       |                                          |
       |-- ② Authorization Request ------------->|
       |<- ③ Authorization Code -----------------|
       |                                          |
       |-- ④ Token Request (code交換) ----------->|
       |<- ⑤ Access Token ------------------------|
       |                                          |
       |-- ⑥ Credential Request ---------------->|
       |<- ⑦ VC 発行(credentialレスポンス) ------|
  • Issuer はまず Credential Offer(QR コードや deeplink)でウォレットを招待します
  • ウォレットは通常の OAuth 2.0 フローでアクセストークンを取得し、VC を要求します
  • 発行された VC はウォレット内に安全に保管されます

活用例: マイナンバーカードの読み取り → 自治体サーバーが VC を発行 → スマホのウォレットに保存


2. OID4VP(OpenID for Verifiable Presentations)― VP を提示する

ユーザーが RP(Verifier)に対して VP を提示して属性証明するためのプロトコルです。既存の OIDC の Authorization フローを拡張しており、vp_token という新しいレスポンスタイプを追加しています。

[ユーザー/ウォレット]                    [RP(Verifier)]
       |                                       |
       |<- ① Authorization Request ------------|
       |   (presentation_definition 付き)      |
       |                                       |
       |  ウォレットが条件に合う VC を選択        |
       |  VP を生成(holder の署名を付与)        |
       |                                       |
       |-- ② vp_token を返送 ---------------->|
       |                                       |
       |              RP が VP を検証           |
       |<- ③ ログイン完了/属性情報を利用 --------|

Authorization Request の例(OID4VP)

GET /authorize?
  response_type=vp_token
  &client_id=https://hospital.example/callback
  &presentation_definition={
    "id": "age-check",
    "input_descriptors": [{
      "id": "age-credential",
      "constraints": {
        "fields": [{
          "path": ["$.credentialSubject.isAdult"],
          "filter": { "type": "boolean", "const": true }
        }]
      }
    }]
  }
  &nonce=abc123

presentation_definition で「どんな VC が必要か」を宣言します。ウォレットはこの定義に合う VC を選んで VP にして返します。RP は受け取った vp_token を検証してログインを許可します。

nonce は毎回ランダムな値を使うことで、VP の使い回し(リプレイ攻撃)を防いでいます。

活用例: 病院サイトにログイン時、「成人であること」を VP で証明 → 氏名・生年月日は開示不要


3. SIOPv2(Self-Issued OpenID Provider v2)― ウォレット自身が IdP になる

通常の OIDC では Google や Microsoft などの外部 IdP が認証を担いますが、SIOPv2 では ユーザーのウォレット自体が IdP(OpenID Provider)として振る舞います

通常の OIDC:  ユーザー → RP → Google(外部 IdP) → RP
SIOPv2:      ユーザー → RP → ウォレット(自己発行 IdP) → RP
  • 外部 IdP への依存がゼロになり、完全に分散型の認証が実現します
  • RP は sub_jwk(ユーザーの公開鍵)を使って署名を検証します
  • OID4VP と組み合わせることで「ウォレットで認証しつつ VC も提示する」という強力なフローが組めます

活用例: 行政サービスへのログインで、Google アカウントなしにマイナンバー由来の VC だけで本人確認を完結させる


3つのプロトコルの使い分け

やりたいこと 使うプロトコル
機関から VC をウォレットに取得したい OID4VCI
VC の属性を RP に証明してログインしたい OID4VP
外部 IdP なしで分散認証したい SIOPv2
上記すべてを組み合わせたい OID4VCI + OID4VP + SIOPv2

実際のユースケース

eKYC(本人確認)

マイナンバーカードの VC をウォレットに保存し、銀行口座開設時に VP として提示。紙不要・即時確認が実現します。

学歴・資格証明

大学が発行した卒業証書 VC を企業の採用システムに VP 提示。偽造不可・即時検証が可能です。

ワクチン接種証明

EU Digital COVID Certificate はほぼ VC 相当の仕組みです。入国審査で QR スキャンして検証します。

年齢確認(SNS / EC サイト)

「18歳以上」だけを VP で提示。生年月日・名前は開示しないプライバシー保護設計が実現できます。


VC と従来の JWT / SAML との違い

特徴 JWT(旧来) SAML VC/VP
発行者管理 中央集権(IdP) 中央集権(IdP) 分散(DID)
保持場所 クライアント Cookie/Storage SP セッション ユーザーのウォレット
選択的開示 △ 基本不可 ✗ 不可 ✅ SD-JWT などで可能
オフライン検証 ✅ 可(公開鍵配布) △ 要メタデータ ✅ DID 解決で可能
相互運用性 高(RFC 7519) 中(XML) 高(W3C 標準)

まとめ

  • VC = 発行者が署名した「改ざん不可能なデジタル証明書」
  • VP = 保持者が必要な情報だけ選んで提示する「封筒」
  • DID = 発行者・保持者を分散的に識別する「識別子」

OID4VC により既存の OIDC エコシステムとも統合できるため、今後はパスポート・学位・医療記録など多くの場面で使われるようになるでしょう。

まずは did:key + @digitalbazaar/vc ライブラリでローカル動作を試してみることをおすすめします。


参考リンク・お試しライブラリ

仕様書

ライブラリ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?