本記事は生成AIと共同で執筆しています。事実関係は可能な範囲で公式ドキュメント・一次情報と照合していますが、誤りが含まれている可能性があります。重要な判断を行う前にご自身でも一次情報をご確認ください。
デジタルアイデンティティとは何か、W3C は Verifiable Credentials の何を決めていて、何を決めていないかの続きです。前 2 本で「形」は標準になっていること、「誰を発行者として信じるか」は規格の外に残ることを見ました。今回は保持者の側、つまりウォレットの役割と、その「信じるか」を実際に運用している例を見ます。
二つの「ウォレット」
同じ語が別のものを指しているので、資料を読むときに毎回の判別が要ります。
| 意味 | 例 | |
|---|---|---|
| 決済ウォレット | 支払い手段・鍵の入れ物 | Apple Pay、PayPay、MetaMask |
| アイデンティティ・ウォレット | 属性証明の保持・提示 | EUDI Wallet、EDC の identity-hub、Microsoft Authenticator |
Ocean Protocol(データ流通の実装)や、その上に構築された Pontus-X(データスペース。公開カタログを覗いた記録があります)が wallet と言うときは前者(EOA = Externally Owned Account、秘密鍵から導かれるアカウント)を指し、Gaia-X や EDC (Eclipse Dataspace Components) が言うときは後者を指しています。以下は後者の話です。
表に挙げた EUDI Wallet (European Digital Identity Wallet) は、EU が加盟国に対して市民や居住者への提供を求めているデジタル身分証アプリで、2024 年 4 月の規則 (EU) 2024/1183(通称 eIDAS 2.0)が根拠になっています。EDC の identity-hub は、個人ではなく組織のサーバ側で資格情報を保持する実装です。同じ「ウォレット」でも、想定している持ち主が個人か組織かで作りが変わります。
ウォレットが担う 4 つの機能
ウォレットという名前のアプリを使うかどうかではなく、この 4 つを誰かが担っているかどうかが問題になります。
ここで言う手元の検証環境は、Gaia-X Lab の Compliance Service (2.12.0) を Docker で動かし、自分で書いた自己記述を提出して適合性証明を受け取り、その提示を Ocean Node のダウンロード認可の条件に差し込んだものです。構成と組み立ての経緯は許可リストに載っている本人が、ダウンロードできない ── Gaia-X の適合性証明を Ocean の認可に差し込むに書きました。この環境では、資格情報を提出するスクリプトが鍵を読み、参加者の自己記述・利用規約への同意・法人番号の 3 通を 1 つの提示物 (VP、Verifiable Presentation) に束ねて署名しています。②の保管と、複数の資格情報をまとめて出す部分に相当する動作はここで行っていますが、①の「鍵を外に出さない」という意味での保護には達しておらず、秘密鍵はファイルとして置いてあります。③についても、相手の要求に応じて選ぶのではなく、決め打ちの 3 通を束ねているだけです。
const key = await importPKCS8(readFileSync(join(root, 'certs', 'key.pem'), 'utf8'), ALG)
// …
const vpJwt = await new SignJWT(vp)
.setProtectedHeader({ alg: ALG, typ: 'vp+jwt', cty: 'vp', iss: DID, kid: KID })
.sign(key)
埋まっていないのが 4 つ目です。
4 つ目が無いと、何を判定していることになるか
手元のポリシーサーバには、次のように書いてあります。
本来これは提示者が鍵で署名した所有証明(VP の holder binding、あるいはウォレット署名)で示すべきものである。ここではローカル検証のため、DID と実行主体のアドレスの対応表を外から与えている。
対応表を外から与えているので、この構成では「適合性証明という文字列を持っている者」なら誰でも通ります。VC-JWT は bearer token、つまり持っていること自体が権利になる形式(乗車券に近い性質)なので、ログや通信路やブラウザの拡張機能から一度写しが漏れれば、拾った第三者がそのまま提示できます。署名は正しく、有効期限も切れていないため、検証者の側からは正規の提示と区別がつきません。
標準的な解き方は次の流れです。
- 発行者が資格情報の
credentialSubject.id(DID = Decentralized Identifier、分散識別子) を保持者のものにする(手元では、前の記事で開いたとおり発行者側の URL が入っています) - 検証者が nonce(毎回変わる使い捨ての値)と audience(提示先を示す識別子)を出す
- 保持者が提示物に nonce と audience を入れて、自分の鍵で署名して返す
- 検証者が「提示物の署名鍵」と「資格情報の subject の DID に結びついた鍵」が一致することを確かめる
要点は 2 と 3 で、検証者が毎回違う値を出し、それに対する署名を求めるところにあります。過去の提示物を拾っただけの第三者は、今回の nonce に対する署名を作れないので通りません。audience を含めるのは、ある検証者に出した提示物を別の検証者に転送されることを防ぐためです。
手元では発行者と保持者が同じ鍵になっているので、そこを分けるのが素直な直し方です。ただし後述するように、既存の機構を使うもう 1 つの経路もあります。
トラストアンカーとは何か
前の記事で「誰を発行者として信じるかは規格の外」と書きました。この「信じる」の実体が、トラストアンカー (trust anchor) と呼ばれるものです。定義としては、検証の連鎖をたどっていった先の出発点、つまり「それ以上さかのぼらずに信じると決めて、事前に手元へ置いておく鍵や証明書」を指します。
抽象的なので、学認 (GakuNin、学術認証フェデレーション。国立情報学研究所 (NII) の事業として学術認証運営委員会が運営) の運用を見ると分かりやすくなります。学認は SAML (Security Assertion Markup Language) という規格に基づく大学間の認証連携で、実装には Shibboleth がよく使われています。この方式では、参加するサーバどうしが互いの接続先 URL と署名鍵を知っている必要があり、その情報を記述したものをメタデータと呼びます。SAML とメタデータの中身については学認のメタデータを開いて読むで、実データを見ながら別に書きました。
学認では、参加する各機関の IdP / SP のメタデータを 1 つの XML にまとめ、学認が 1 本の鍵で署名して配信しています。各参加サーバは、その署名者証明書をあらかじめ手元に置いておき、署名が検証できた場合にだけ名簿を読み込みます。つまり、数百件のエンティティを個別に信頼するのではなく、名簿に署名する 1 本の鍵だけを信頼すれば済む形にしてあります。
実際に取得してみます。
curl -s -o gakunin.xml https://metadata.gakunin.nii.ac.jp/gakunin-metadata.xml
python3 -c '
import xml.etree.ElementTree as ET
MD = "{urn:oasis:names:tc:SAML:2.0:metadata}"
r = ET.parse("gakunin.xml").getroot()
ents = r.findall(MD + "EntityDescriptor")
idp = [e for e in ents if e.find(MD + "IDPSSODescriptor") is not None]
sp = [e for e in ents if e.find(MD + "SPSSODescriptor") is not None]
print(r.get("Name"), len(ents), len(idp), len(sp), r.get("validUntil"))
'
GakuNin 650 419 231 2026-08-24T14:00:00Z
2026-08-12 時点で 650 エンティティ(IdP 419、SP 231)、ファイルは 5,655,173 バイト(約 5.7 MB)で、この名簿自体の有効期限は 2026-08-24 でした。期限があるので、参加サーバは定期的に取り直します。
署名者の証明書は XML の署名部分に埋め込まれています。
python3 -c '
import re, base64
d = open("gakunin.xml", encoding="utf-8").read()
m = re.search(r"<ds:X509Certificate>([^<]+)</ds:X509Certificate>", d)
open("signer.der", "wb").write(base64.b64decode("".join(m.group(1).split())))
'
openssl x509 -inform DER -in signer.der -noout -subject -issuer -dates
subject= /C=JP/O=GakuNin - Japanese Academic Access Management Federation/CN=GakuNin Metadata Signer - G2
issuer= /C=JP/O=GakuNin - Japanese Academic Access Management Federation/CN=GakuNin Metadata Signer - G2
notBefore=Nov 14 07:04:41 2017 GMT
notAfter=Nov 14 07:04:41 2027 GMT
出力は macOS 標準の LibreSSL のものです(Homebrew の OpenSSL 3 では subject=C=JP, O=…, CN=… の形式になりますが、値は同じです)。subject と issuer が同じ、つまり自己署名の証明書です。公的な認証局から辿れるわけではなく、「これを信じる」と各参加機関が決めて手元に置いている点が、まさにトラストアンカーの性質を表しています。有効期間は 2017 年から 2027 年までの 10 年です。
「学認に参加している」という状態は、この名簿に自分のエンティティが載り、かつ自分も署名者証明書を信じている、という双方向の関係になります。名簿そのものを信頼の対象にするのではなく、名簿に署名する鍵を信頼の対象にしているのが要点です。Verifiable Credentials でも同じ構造が要りますが、そこは仕様の外なので、エコシステムごとに用意されています。Gaia-X の場合はGaia-X Registry には何が入っているのかで実物を見ます。
学認とウォレット方式の構造差
| 学認(SAML / Shibboleth) | ウォレット(Verifiable Credentials) | |
|---|---|---|
| 属性の流れ | IdP から直接 SP へ | Issuer → Holder → Verifier |
| IdP が提示先を知るか | 知る(毎回のログインを見る) | 知らない |
| 属性の選択 | IdP の属性送出ポリシー(管理者が決める) | 利用者がウォレットで選ぶ |
| 提示できる相手 | フェデレーション参加 SP | フェデレーション外にも提示できる |
| オンライン性 | IdP が稼働していないと成立しない | 事前発行なので提示時に Issuer 不在でも成立 |
| トラスト管理 | NII がメタデータを署名して集約(運用実績がある) | Trust Anchor List を各エコシステムが個別に整備 |
最下段が要点です。Verifiable Credentials まわりで課題として挙げられることの多い「誰を信頼できる発行者とするか」を、学認は 2010 年度の本格運用開始以来 15 年を超える運用実績がある形で既に持っています。日本で VC 基盤を作るときに学認が土台になっているのは、この部分を引き継げるからだと読めます。
一方、学認の構造では扱いにくいものもあります。フェデレーション外の相手への提示、属性単位の選択的開示、そして IdP が閲覧履歴を把握する点です。
日本での実装例
在学資格証明を VC 化する実証が、デジタル庁の事業として 2026 年 3 月 2 日から 15 日まで実ユーザー参加で行われ、3 月 17 日に報告会が開かれています。構成は、学認の IdP を入口にして NII が開発した発行基盤が VC を発行し、利用者は Microsoft Authenticator で保持し、検証側が受け取る、という流れでした。
| 役割 | 担当 |
|---|---|
| 全体取り纏め・実証受託者・検証側 | 西日本旅客鉄道 |
| デジタル資格証明発行基盤システム | 国立情報学研究所 (NII) |
| システム連携・在学資格発行・学生参加 | 大和大学、京都女子大学、大阪大学、広島大学 |
| 在学資格の検証 | コシダカホールディングス |
| VC 実装支援・技術監修 | OpenID ファウンデーション・ジャパン |
| 保持者のウォレット | Microsoft Authenticator(既製品) |
大学側の接続形式が 3 種類用意されていた点も、既存の学内認証基盤の構成が大学ごとに異なることを前提にした設計だと読めます。
| 形式 | 採用校 |
|---|---|
| AP フロント形式(大学所有 IdP 型) | 大和大学 |
| AP フロント形式(SaaS 型) | 広島大学、京都女子大学 |
| IdP フロント形式 | 大阪大学 |
holder binding をどう扱っていたか
この実証では、4 つ目の機能にあたる部分を、公開資料から読み取れる範囲では二経路の突合で扱っています。提示された在学証明 VC と、デジタル認証アプリ経由のマイナンバーカードによる本人確認を、その場で突き合わせて同一人物と判定する構成です(報告資料には「在学証明書・マイナンバーカードを突合し、学生認証を実施」とあり、暗号的な holder binding を併用しているかどうかまでは書かれていません)。
純粋な暗号的 holder binding ではありませんが、公開されている範囲では、既製のウォレットで暗号的な holder binding まで担保する構成が一般的ではない時期の実装として参考になります。事前に管理者が書く静的な対応表と違い、その場で 2 つの独立した経路から来た身元を突き合わせる構成なので、公開されている説明を読む限り、資格情報の写しを拾っただけでは通らない作りに見えます。
手元の構成に当てはめると、Ocean 側のウォレット署名(nonce に対する署名)を第二の経路として使えば、対応表を外部から与える必要がなくなります。既存の機構だけで済むので、次の一手としてはこちらのほうが現実的に見えます。
アーカイブのアクセス制御に当てはめる
以上を、筆者が実際に検討している、利用制限のかかった資料へのアクセス制御に当てはめてみます。調べた範囲では、現実的な順序は次のようになりそうです。
- 国内研究者の所属証明は学認で足ります。
eduPersonScopedAffiliation(faculty@u-tokyo.ac.jpのように、役割と所属ドメインを組にした標準の属性)で「特定の大学の教員である」ことは既に証明できるので、VC を持ち出す必要は薄い - VC が要るのは学認の外に出るときです。海外の研究者、フェデレーション非加盟の機関、市民アーキビスト、そして「所属」ではなく「倫理審査を通過している」「コミュニティの承認を得ている」のような、大学が発行しない資格
- 2 の後者では、証明を出す権威が大学でも行政でもなく当該コミュニティになります。技術は既存の実証がそのまま使える一方、そのコミュニティを発行者として承認する枠組みは、学認の名簿にも Gaia-X の名簿にも、現時点では区分が用意されていません
3 番目は、暗号や仕様からは出てこない部分です。
ここで関係してくるのが、NII と伊藤忠テクノソリューションズ (CTC) が 2024 年 10 月から 2026 年 3 月まで実施した、学術機関のデジタル資格証明の標準化に向けた共同研究です。学位・学修歴・学生証を対象に、学認のトラストフレームワークを参考にして、デジタル署名を検証できるアーキテクチャを検討する、という枠組みでした。トラストフレームワークというのは、誰が発行者になれるか、何を証明してよいか、規則に反したときにどう扱うかといった、技術仕様の外側にある取り決めの集まりです。学認は SAML を前提としたそれを既に持っているので、VC でも通用する形をそこから起こすことになります。
公表資料では、W3C の Verifiable Credentials と ISO/IEC 18013-5(運転免許証などをスマートフォンで提示するための国際規格。この形式を mdoc と呼びます)のどちらを採るかは未決とされ、課題として技術規格の分断、属性定義や多言語対応の不統一、正当な機関を認証する仕組みの不足が挙げられています。3 番目の課題は、ここまで見てきた「誰を発行者として信じるか」と同じ論点です。この共同研究は 2026 年 3 月で期間を終えているので、後続の枠組みが立ち上がる時期にあたります。アーカイブ側の要件を出すなら、このあたりという面はありそうです。
コメント
…