祝・RFC 9901! SD-JWT がインターネット標準に―― デジタルIDウォレット時代の「必要なところだけ見せる」新ルール〜「Verifiable Credentials とアイデンティティ・ウォレットを支えるコア・フォーマット SD-JWT の概要」

1. RFC 9901 誕生

2025年11月19日、「Selective Disclosure for JSON Web Tokens」、通称 SD-JWT (エスディージョート)を定めた仕様が RFC 9901 として公開されました。

著者は以下の3名です。

JSON Web Token (JWT) [RFC 7519]JSON Web Signature (JWS) [RFC 7515]は、IDトークンJWTアクセス・トークン[RFC 9068]で広く使われてきたインターネット標準です。
そこに「必要な部分だけ、あとから切り出して見せられる」という新しい能力を与えるのが SD-JWT です。

JOSE ファミリー(JWS / JWT / JWE)の系譜に、
「Selective Disclosure(選択的開示)」という新しい柱が正式な RFC として加わった、と位置付けることができます。


2. SD-JWT は何のための仕様か

2-1. 従来の JWT の課題:「随時発行」or「全部入り」

従来の JWT は、「署名済みの JSON の塊」をそのままサービスに渡すモデルが基本でした。

  • 発行者(IdP や認証サーバ)がユーザー情報をまとめて JWT に詰める
  • 受け取ったサービス(リライングパーティ)が、その中身を全部読める

これは、動的に随時発行するOpenID Connectのようなモデルならば、選択的開示もデータ最小化もRP間のアンリンカビリティ(RP+RP’-U Unlinkability)も実現できる(典型的には、PPID=Pairwise Pseudonymous Identifier を使います)のですが、「使用目的がわからない状態であらかじめ証明書を発行しておいて後から使う」ということをやりたい場合、いずれもできないという課題を抱えていました。

例えば「年齢」「住所」「氏名」「メールアドレス」が1つの JWT に入っているとき、サービス側は本当は「20歳以上かどうか」だけ分かればよい場面でも、事前発行してためておいたJWTを使う場合には、住所や氏名まで全部見えてしまいます。

この「全部入り」構造は実装としてはシンプルですが、貯めておいて使うということをしたい場合、

  • 選択的開示ができない=データ収集最小化原則を満たせない
  • RP+RP’-U Unlinkability も満たせない

といった限界をもっていました。(実装のシンプルさとのトレードオフなわけですが。)

2-2. ウォレット・モデルとの相性

一方、貯めておいたものを後から使いたいというユースケースはたしかにあります。電波が通じないところでの利用や、学校が潰れてしまった後の卒業証書の提示などが典型的なユースケースです。「電波が通じ無いことなんてそんなにある?」と思うかもしれませんが、それは日本が恵まれた環境にあるからで、欧州の石造りの建物の中など、電波状況はお寒い限りですし、駅からちょっと離れただけで、マンハイムなどの中核都市でも、屋外でも電波が通じなくなってしまいます。広大なアメリカなどももちろんそうですね。そういうこともあってか、欧州の EUDI ウォレット など、最近のアイデンティティ・ウォレットでは、

  • 1つのウォレット(スマホアプリ)が複数の Verifiable Credentials(VC) を貯めておいて、
  • 利用者が「このサービスには、この項目だけを見せる」と選択して提示する

というモデルが前提になっています。これならば、発行するときだけ、ウォレットと発行者はONLINEで繋がっていれば良いことになるからです。

ここで必要になるのが、

「貯めておいたひとつの署名付きデータの中から、後から一部だけ選んで、安全に見せられるフォーマット」

です。これを定義しているのが RFC 9901 の SD-JWT です。


3. SD-JWT を一言でいうと

非常にざっくり言うと、SD-JWT は次のような仕組みです。

  1. ベースは従来どおり 署名付き JWT(JWS)
  2. ただし、一部のクレームは「ハッシュ値だけ」を JWT の中に入れておく
  3. 元の値とソルトをまとめた Disclosure を別に持っておき、必要なときだけ Verifier に渡す
  4. Verifier は
    • Disclosure からハッシュを再計算し
    • それが署名済み JWT の中のハッシュと一致するかを検証することで
    • 「確かに Issuer が署名したデータの一部である」と確認できる

さらに、トークンの不正な転送を防ぐために、トークンを 利用者の鍵ペアに紐づける仕組み(Key Binding) も用意されています。
これと組み合わせた構造を SD-JWT+KB と呼びます。


4. 3人の登場人物と SD-JWT の流れ

SD-JWT の基本的な登場人物は、VC の世界と同じです。

  • Issuer(発行者)
    役所、銀行、大学など。事実に責任を持つ組織。
  • Holder(保持者)
    ユーザー本人。スマホのウォレットアプリで資格情報を保持する。
  • Verifier(検証者)
    サービス提供者。銀行口座開設、年齢確認、入館管理など。

典型的な流れは以下のとおりです。

  1. 発行(Issuance)
    • 発行者 (Issuer) はユーザーの属性情報(住所・生年月日など)を JSON にまとめる
    • 「後から選択的に開示したい項目」については、
      値 + ランダムなソルト からハッシュを計算し、そのハッシュだけを JWT に埋め込む
    • 元の値 + ソルト は Disclosure として別に用意する
    • 署名付き JWT と複数の Disclosure をまとめて「SD-JWT」として Holder に渡す
  2. 提示(Presentation)
    • ユーザーがあるサービスを利用しようとする
    • ウォレットは SD-JWT の中から、Verifier に見せたい項目の Disclosure だけを選ぶ
    • 署名付き JWT + 選択した Disclosure +(必要に応じて Key Binding JWT)を Verifier に送る
  3. 検証(Verification)
    • Verifier は
      • Issuer の公開鍵で JWT の署名を検証
      • Disclosure を使って各項目のハッシュを再計算し、JWT 内のハッシュと一致することを確認
    • これにより、「Issuer が署名したデータの一部である」ことを確かめつつ、未開示項目は守られる

5. 少しだけ技術的な話:ソルトと Disclosure

5-1. ソルト付きハッシュによる選択的開示

各クレーム(住所や誕生日など)は、

  • ソルト + 値 +(場合によってはクレーム名)

からハッシュを計算し、そのハッシュ値を JWT に埋め込みます。

実際に開示するときは、Disclosure として

  • 「ソルト・クレーム名・値」

を Verifier に渡します。

Verifier は同じ手順でハッシュを再計算し、JWT 内のハッシュと一致するかどうかで改ざんの有無を確認します。
ソルトが含まれているため、未開示クレームの値は推測されにくくなります。

5-2. Disclosure という「開示パーツ」

RFC では Disclosure は Base64url でエンコードされた JSON 配列として定義されており、例えば次のような形になります。

  • 要素 0: ソルト
  • 要素 1: クレーム名(配列要素の場合は省略されることもある)
  • 要素 2: クレーム値

ウォレット内部では、

「ひとつの大きな資格情報を、細かい Disclosure の集合として持っておき、必要なものだけ取り出して送る」

というイメージで捉えると分かりやすいと思います。

5-3. Key Binding と SD-JWT+KB

SD-JWT だけだと、「トークンをコピーして他人が提示してしまう」攻撃(リプレイ攻撃)のリスクが残ります。
そこで RFC 9901 は、SD-JWT を Holder の鍵ペアに結び付ける Key Binding を定義しています。

  • SD-JWT の中に Holder の公開鍵(またはその参照)を含める
  • Holder は提示時に、その鍵で署名した Key Binding JWT (KB-JWT) を一緒に送る
  • Verifier は
    • SD-JWT と KB-JWT が同じ鍵に結び付いていること
    • その秘密鍵を Holder が実際に持っていることを検証する

Key Binding を必須にした SD-JWT+KB にすることで、VCのコピーに対する耐性が高まります。

: Holder Binding には、Key Binding, Claim Binding, Biometrics Binding とあります。+KBはこのうちKey Binding を実現します。ただし、Key Binding の場合、デバイスなど鍵を保管しているメディア自体を譲渡されてしまうと、なりすましが可能である(これを、Alice-to-Bob Attack などといいます)という課題はあります。銀行口座の売買などがまさにそれにあたります。これを防ぐには、通常、Biometrics Binding が必要です。

5-4. JSON 構造・配列への対応

RFC 9901 は、単純なフラットな JSON だけではなく、

  • ネストしたオブジェクト
  • 配列要素ごとの開示
  • 「ダミーのハッシュ(Decoy Digests)」によるパターン隠し

といったケースへの対応も定義しています。

これにより、

  • 「一人ひとり、まったく同じ構造の資格情報」だと推測されないようにする
  • 開示した項目数だけでトラッキングされるリスクを下げる

といった工夫が可能になります。


6. SD-JWT と VC・アイデンティティ・ウォレット

6-1. SD-JWT VC:VC フォーマットとしての位置づけ

IETF では、RFC 9901 の SD-JWT を用いて Verifiable Credentials を表現する仕様 として
「SD-JWT-based Verifiable Credentials (SD-JWT VC)」 ドラフトが策定されています。

これは、

  • JSON 形式の VC を
  • SD-JWT で選択的開示可能にし
  • その検証方法を定める

という役割を持つ仕様です。現在WG Last Call に入る前のWGレビュー中で、筆者もレビュワーとして28点ほど、エディトリアルな改善(一部テクニカルととれるものもありますが)を提案しています。(アメリカ人やドイツ人が書くと、一文が長くなって読みにくくなるので、それを分解したりとか、受け身の多用によって、義務の実行者が曖昧になる問題とか、セキュリティ、プライバシー、公平性への考慮事項とか。)また、これをするにあたって、仕様ドラフトに含まれる例を検証するために、SD-JWTをデコード・検証するための静的なHTML/JavaScriptページ「sd-jwt-decoder」もつくりました。GitHubにもおいてあります(HTML 1枚ペラなので、ローカルでも簡単に動かせます=わたしが飛行機の上でドラフトを検証するのに必要だった)ので、バグなど見つけたらプルリクお願いします。

6-2. EUDI ウォレットでの利用

欧州委員会の EUDI Architecture Reference Framework (ARF) では、欧州デジタルIDウォレットで利用される標準として、

  • OpenID for Verifiable Credentials (OpenID4VCI / OpenID4VP)
  • SD-JWT / SD-JWT VC
  • ISO/IEC 18013-5 のモバイル運転免許証 (mDL)

などを組み合わせて利用することが示されています。

この文脈では RFC 9901 は、

「EUDI ウォレットなどのアイデンティティ・ウォレットに格納される VC を
JWT/JOSE ベースで実現する際のコア・フォーマット」

という位置づけになります。

6-3. ウォレット利用者から見たメリット

一般利用者の体験としては、例えば次のような形になります。

  • 年齢確認
    コンビニでは「生年月日」ではなく「20歳以上である」の真偽だけを提示
  • 住所確認
    通販サイトには「配送に必要な住所」だけを提示し、他の属性は見せない
  • 本人確認(KYC)
    銀行や証券会社には必要な属性だけを組み合わせて提示し、同じ VC を他サービスで再利用する

これらはすべて、「1つの署名付きデータを細かく分解して必要な部分だけ取り出す」という SD-JWT の性質によって実現されます。


7. エコシステムの広がり(概要)

すでに複数の OSS や商用ソリューションが SD-JWT / SD-JWT VC を実装に取り込みつつあります。

  • 諸種ウォレット・フレームワークでの SD-JWT サポート:わたしが理事を務めている、Siros Foundation の出しているwwWallet もその一つです。
  • Authlete などによる SD-JWT VC 発行エンドポイントの提供
  • EUDI ウォレット・プロジェクトや SPRIND の取り組みにおける採用
  • OpenID Foundation による OpenID4VC と SD-JWT VC を組み合わせた高セキュリティプロファイル(HAIP)策定

こうした動きの上に、RFC 9901 は「土台の一枚」として位置付けられます。


8. まとめ

  • RFC 9901 は、JWT / JWS に「選択的開示」という能力を与えるインターネット標準。
  • SD-JWT は、
    • 署名付き JWT の中にはハッシュだけを入れ
    • 元の値とソルトを Disclosure として必要なときだけ提示し
    • それでも Issuer の署名による真正性を保つ
      というフォーマットを定義している。
  • Key Binding を加えた SD-JWT+KB により、ウォレットの所有者に紐づいた安全な提示が可能になる。
  • SD-JWT VC ドラフトや EUDI ARF、OpenID4VC のプロファイルと組み合わさることで、
    アイデンティティ・ウォレットに格納される VC の中核フォーマットの一つ として使われていく。

JOSE / JWT の系譜に新しいピースが加わり、ウォレット・ベースのデジタルID基盤の現実的な実装パターンが、ひとつ明確になったと言えます。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください