SSI/VCモデルとHyperledger Indy/Ariesを使ったシステム構築実証[前編]

はじめに

GMOグローバルサイン・ホールディングスCTO室でデジタルアイデンティティーの研究開発をしている神沼(@t_kanuma)です。

この記事では次世代のID管理を担うと目される自己主権型アイデンティティー(Self-Sovereign Identity、SSI)について述べます。

前編となるこの記事では、SSIという思想、その思想を実現するVerifiable Credentialというモデル、そしてそのモデルを実現するための技術の1つであるHyperledger Indy、Ariesについて述べます。

そして後編では、私が行った小さなPoC、ユースケース「年齢認証」でHyperledger Indy、Ariesを使い、実際にシステムを構築・開発できるか?について、アプリケーションのデモ動画を含めご説明します。

SSIとVerifiable Credentialモデル

背景・課題

現在のインターネットは安全とは言い難い面があると思います。

パスワード認証

  • パスワードは世界で4億件も漏洩しています。
  • 現在の認証方式の主流であるパスワード認証は十分ではありません。

中央集権による管理

  • 私達のIDはプラットフォーマーによって管理されているのが実情だと思います。
  • プラットフォーマーへの依存度が高いと、次のようなリスクがあると思います。例えば、私はインターネットで利用するサービスのほとんどにGoogleのアカウントを使っています。万が一、私のIDがGoogleに破棄されたらものすごく困ってしまいます。

情報の相関付け

  • 複数のサービス提供者が共謀し、例えばメールアドレスをキーに互いが持つ情報を結合することで個人を特定できてしまう可能性があります。
  • シングルサインオンサービスを提供する事業者は、顧客のインターネット上の生活、すなわち「いつどのサービスを利用したか」を把握することが技術的には可能だと思います。

これらの課題を解決するため、中央集権を介さずに自分自身でデジタルアイデンティーを保持し、コントロールする。言い換えればIDの主権を個人に還す、その思想、概念が自己主権型アイデンティティー(SSI)です。そしてその思想を実現するモデルがVerifiable Credentialモデル(VCモデル)になります。
ここで特筆すべき点として、非中央集権、分散型のコンセプトから、SSIの世界では弊社のような電子認証局の概念がありません。

VCモデル

一言で言うと…

  • 一言で言えば、現実世界の紙や物理的実体を伴うPaper Credential Modelをオンライン化しましょう、というものです。
  • 言うまでもありませんが、オフライン、現実世界では、私たちはCredential(運転免許証や社員証、卒業証明書のような私達の身元を特定するモノ)を自分の家の中や財布に保持し、自身で管理しています。インターネット上でもそうしましょうと言うことです。VCモデルでは、個人は主にスマートフォンにCredentialを格納することになります。
  • いつ、どこで、何のために自身のCredentialを使うか、それが私達次第になるモデルです。具体的な変化の一部として以下の点が挙げられると考えます。
    1. Credentialを利用する能力が発行元(現在でいうIdentity Provider)に依存しなくなり自分次第になります。我々が普段の生活において物理的実体を伴う運転免許証や社員証をどこかで提示する度にいちいちその発行元に問い合わせて許可をもらうということはまず無いと思います。それと同様です。
    2. 発行元がCredentialの提示をトレースできなくなり、個人のプライバシーが保たれます。これはVCモデルではVerifierとIssuerの関係が疎結合になっているためです。普段の生活において、紙の資格証明書や住民票を何の目的でどこでどう提示しようと、その発行元はそれをトレースしていないのと同じです。

モデル図


Daniel H Hardman,CC BY-SA 4.0,link

3つの登場人物と用語

3つの登場人物
  1. Holder
    • Credentialを保持、管理、使用する個人です。
  2. Issuer
    • HolderにCredentialを発行する企業などの団体または個人です。
  3. Verifier
    • Holderから後述するProofを受け取り、その正当性を検証する企業などの団体または個人です。
用語

(いくつかの団体がSSI/VCモデルの実現に向けた仕様を策定している状況の中で、ここからはHyperledger Indy/Ariesのスコープに留まります。)

  • Registry
    • そこにあるデータが改竄されていないと信頼できるデータストレージです。後述するIssuerのパブリックなDIDを保管します。例としてブロックチェーンが挙げられます。
    • VerifierはRegistryに保管されている情報を使い、Holderが提示するProofを検証します。(詳しくは後述します。)
    • Registryには、Credentialなどのプライベートな情報は一切格納されません。(ここがHL Fabricなど他のブロックチェーンとの大きな差異になると思います。)
  • Credential
    • 前述のとおり、運転免許証や住民票のような私達の身元を特定する情報の集合です。
  • Claim
    • Credentialの中の1つ1つの情報です。
    • 例えば運転免許証であれば、住所や生年月日に当たります。
  • Proof/Presentation
    • Verifierに提示するためのClaimの集合です。
    • 詳しくは後述しますが、Proofは、異なるIssuerの複数のCredentialから必要なClaimを集めて作成することができます。
  • Agent
    • Holder、Issuer、Verifierを代理するソフトウェアアプリケーションです。
    • Agentの形態はモバイルアプリ、Webアプリ、IoTデバイスなどです。
    • Agent間の通信は後述するPairwise DIDを用いて行ないます。
    • 各Agent間に強弱、優劣は無く、互いが平等な立場でP2P型・非同期メッセージング方式で通信をします。
    • ちまたのメッセージ/チャットアプリのように互いにメッセージを送りあいながら(ただし中央集権的サーバを介さずに)、話を進めていきます。
  • Wallet
    • 各AgentがCredentialと後述のDIDの秘密鍵を保管するセキュアなストレージです。
  • DID
    • DID(Decentralized IDentifier)は、UUIDのような、SSIの世界で各人を一意に識別するためのIDです。
    • DIDには公開鍵ペアが紐づいており、これを用いてセキュアな通信を実現します。
    • DIDにはPublicとPrivateの2種類があります。
      • Public DIDは、VerifierがProofを検証するための、IssuerのパブリックなDIDです。Indyにおいては、このDIDに対しそのメタデータである4つのタイプのTransactionが紐づき(詳細は後述します)、Registryに保管されます。
      • Pairwise DID(Private DID)は、Agent間で通信するためのDIDです。Agentは通信相手となるAgentごとに異なるPairwise DIDを生成します。(正確に言うと他Agentとの接続単位で異なるDIDを使います。)

Paper Credential Modelとの比較

  • 紙の偽造は容易にできてしまいます。もしVerifierが見抜けなければそれまでです。VCモデルでは、暗号技術を利用し偽造をとても難しくします。そしてそれは、Verifierの負担を軽減することにもなります。
  • 現実世界で例えばお酒を買う際、年齢を確認するため運転免許証の提示を求めれることがあるかもしれません。その際、住所や生年月日など年齢以外の不要な情報まで提示してしまうことになります。VCモデルでは、ゼロ知識証明(Zero Knowledge Proof、 ZKP)と呼ばれる暗号技術によりそれらの不要な情報、さらには年齢までも隠します。VerifierにはHolderが特定の年齢以上であるかどうか、と言う情報しか渡しません。
  • VCモデルは前述のインターネットの課題を解決すると同時に、上記やペーパーレス化による効率性の向上というメリットを取り込みながら、オフラインでの現在のやり取りをそのままの形でデジタル化すると言えると思います。

パスワード認証との比較

  • DIDに紐づく秘密鍵が、私達のIDの代理になります。すなわちパスワードは使いません。
  • 私達がWebサービスを利用する際は、各サービスごとにDIDを作成します。そうすることで、前述の情報が相関付けされてしまう問題を解決します。

Registryを使ったVerifierの検証方法

  • HolderがVerifierにProofを提示した際、Verifierは”発行元”を確認することで、Proofの正当性を検証します。(その他に、HolderがProofの素であるCredentialのオーナーであること、Claimが改竄されていないこと、Credentialが失効していないことを検証しますが詳細は割愛します。)
  • IssuerはCredential内の各Claimごとに異なる公開鍵ペアでデジタル署名をします。そうすることでVerifierは、Registry内のその公開鍵を使い、発行元を検証することができます。

SSI/VCモデルの適用領域

以下の領域が有望視されています。

  • 認証認可
  • 対面での検証
  • トレーニング、資格の証明
  • 透明で制御可能な権限移譲
  • デジタルな定期報告
    など

仕様、実装、実運用ネットワーク

Verifiable CredentialDIDについてはW3Cにて仕様の策定がなされています。その実装の1つがHyperledger IndyAriesです。実運用されている代表的なIndyネットワークとして、非営利団体Sovrin Foundationが運営するSovrinがあります。

ルートオブトラスト

特筆すべき点として、前述した通り非中央集権のコンセプトから電子認証局のようなルートオブトラストが存在しません。ではVerifierは何を根拠にRegistry上のIssuerの公開鍵を信用したら良いのでしょうか?
ここは私見ですが、”大勢が使っているから大丈夫”という信頼がベースになるのではと思います。

技術

目的

Hyperledger ProjectのSSIに特化したOSSである、Indy(インディ)、Aries(エアリーズ)、Ursa(アーサ)について述べ、それを基盤とするSSIアプリケーションの構成、処理方式、及び構築のポイントについて説明します。

モデルと技術のマッピング


Daniel H Hardman,CC BY-SA 4.0,link

Indy

モデルのRegistryにあたる、以下の性質を持つコンソーシアム型のDistributed Ledger(分散型台帳)です。

  • データ参照においては、パーミッション不要でパブリックにアクセスできます。(ネットワーク参加ノードになる必要もありません。)
  • ノードとしてトランザクション検証に参加するには、既にネットワークに参加している他ノードからのパーミッションが必要です。
  • 前述の通り、プライバシーデータは保管されません。Issuerやトランザクション検証ノードのパブリックなDIDのみが保管されます。
  • IDに特化しています。資産交換やスマートコントラクトの能力は持っていません。
  • コンセンサスプロトコルは、ビザンチン障害トレランスベースです。
    • パブリックブロックチェーンで重要な要素となるインセンティブ設計はありません。
    • PoWのような改竄防御のための強い仕組みはありません。
    • PoWよりも弱い仕組みで改竄を防ぐと言えると思います。ノード参加は許可制で、3f+1ノードの内、悪意のあるノードの数がf以下であれば検証において問題は起きないプロトコルになっています。
  • 各ノードは、トランザクションをKVSとMerkle Treeで、また各トランザクションの積み重ねの中で、最新のデータ(State)をKVSとMerkle Patricia Trieで保管します。(資料を読む限り、ブロックをチェーンする構造はとらないように見えます。)
  • “SSIアプリケーションを作る”という目的の限りでは、関わりは薄くなります。自らネットワークを立ち上げたり、既存ネットワークに参加してトランザクション検証ノードを運用する場合は深く関わることになると考えます。

Indy上のTransaction

Indy上には、Indy固有の何種類かのTransactionが保管されます。ここではメインと呼べる以下の4種類について簡単に述べます。(詳細は後編のPoCの説明にて述べます。)

  1. NYM – Public DIDとそれに紐づく公開鍵を持ちます。一般的にDID Documentと呼ばれるモノに対し、それを構成する情報の一部を持ちます。
  2. ATTRIB – Attribute。Public DIDを所有するAgentのEndpointを持ちます。一般的にDID Documentと呼ばれるモノに対し、それを構成する情報の一部を持ちます。
  3. SCHEMA – VCのClaim定義を持ちます。
  4. CRED_DEF- Credential Defiintion。Schemaの各Claimに対する公開鍵などを持ちます。

Ursa

IndyとAriesをサポートする暗号技術ライブラリです。
IndyとAriesの配下で動くため、SSIアプリ開発者は直接の関与や深堀は必要ないように思います。ゼロ知識証明もUrsaの担当範囲です。

Aries

AgentすなわちSSIアプリケーションのコアとなるフレームワークです。
SSIアプリ開発者はここに深く関わることになると思います。
JavaでのSpringのような一般的なWebフレームワークのように、フレームワークの上に自前アプリが乗ることでAgentとなるイメージをするとわかりやすいと思います。

他エージェントとの通信とプロトコル

他Agentとの通信すなわちメッセージのやり取りは、互いのフレームワークを通して行います。この通信には前述のPairwise DIDを使い、DIDComm ProtocolというAries独自のプロトコルの1種に則り行われます。DIDComm ProtocolはTransport-agnosticに設計されています。それはつまり、様々なネットワークプロトコル(HTTP、WebSockets、Bluetoothなど)上で機能するということです。(今回のPoCではDIDComm over HTTPで通信しています。)
以下は、A AgentとB Agent間の通信のイメージです。
(A Agentアプリ <---> A Agentフレームワーク) <-(DIDComm)-> (B Agentフレームワーク <---> B Agentアプリ)

Ariesは他にもいくつものProtocolを持ちます。これらは例えば、VCモデル内における各イベント(Credentialの発行、Proofの提示など)ごとに異なり、それを完了させるため何回やり取りが発生して、各シーケンスごとに何を送ればよいかなどを定めたプロトコルです。アプリ開発者は、このプロトコルを進めていくことに責務を持ちます。

まとめると大枠にVC発行やProof提示のための個々のProtocolがあり、その中の1つ1つのシーケンス、通信がDIDComm Protocolによって処理されるイメージです。

フレームワーク機能

言い換えるとその細部をフレームワークが隠蔽してくれるものです。

  • Agent間のDIDCommプロトコルでのセキュアな通信
  • Indyへのアクセス(情報格納・取得)
  • Credentialの発行、署名、保存
  • Proofの提示、検証(ゼロ知識証明含む)
  • Walletの管理
  • アプリへのイベント通知、アプリからのリクエスト受付

上記により、アプリ開発者はAriesフレームワークが提供する高レベルなAPI群を適切に呼び出すことでアプリを開発できるわけです。

aca-pyアーキテクチャ

Ariesフレームワーク実装にはいくつか種類があります(後述します)。その中でもサーバサイド用フレームワークとしては現時点でおそらく最も成熟していて、今回のPoCでも利用したaries-cloudagent-python(aca-py)について述べます。

アプリとは別プロセス、そしてアプリにREST APIを提供する。


まず初めに、Ariesの世界では一般的にアプリケーションと呼ぶ部分をControllerと呼びます。(この記事では以降も”アプリ”を言葉として使います。)
Agent間のやり取りはDIDComm Protocolに則りますが、アプリとフレームワーク間については触れませんでした。
aca-pyの特徴として、アプリとaca-pyが別プロセスで動作する点があります。そして、aca-pyはアプリにSwagger API(REST API)を提供します。ここは一般的なWebフレームワークと異なる点です。これにより開発者はアプリを好きな言語で書けるというメリットが生まれます。
また、これまでの話からaca-pyは以下の2つのEndpointを構えることになります。

  • 他AgentとDIDCommで通信するためのEndpoint
  • 自身と1対1で紐づくアプリとHTTPで通信するためのAPI Endpoint
非同期メッセージングアーキテクチャの具体例(Credentialの発行)


Credential発行のためProtocolであるAries RFC 0036: Issue Credential Protocol 1.0をケースに、アプリとaca-pyの間でのやりとりを述べます。
以下、インデックス番号は処理の順序を表します。

  1. Issuerアプリは自身のaca-py(ある意味キューと見なせます)のAPIにCredential発行オファーのメッセージをPostします。
    • このAPIはすぐにレスポンスを返します。
    • (大体のAPIで)正常に受け付けられたかどうかだけが返ってきます。
  2. Issuer aca-pyがメッセージを処理します。
    • 既に接続状態にあるHolderエージェントのaca-pyとDIDComm Protocolでやりとりをします。
    • やりとりの結果は互いのローカルのストレージに保管されます。
    • VC発行のProtocolにおける状態が更新されます。上図で言うと青矢印の文言です。
  3. 状態の更新が各aca-pyから各アプリに通知され、アプリの一部分である非同期のイベントハンドラー(言い換えればコールバックリスナー(馴染みは人それぞれだと思います。))が起動し、イベントを処理します。
    • 青色の矢印、offer_sentとoffer_receivedが該当します。
    • 次はHolderがCredentialのRequestメッセージを自身のaca-py APIに対して投げます。そしてまたDIDComm Protocolが走り、状態が更新されイベントハンドラーが起動し…とVC発行のProtocolが完了するまで進んでいきます。

繰り返しになりますが、このようにP2Pで互いにメッセージを送り合いながらプロトコルを進めていきます。

開発者の責務は、この状態を適切に進めていくことです。
イベントハンドラーはイベントをユーザに返してもよいですし、バックグラウンドの基幹システムに連携してもよいです。またイベントハンドラー内でaca-py APIを呼び返す場合も考えられます。これらはビジネスロジックの設計次第です。

アプリはaca-pyと別プロセスのため、このイベントハンドラーはAPI Endpointを持ちます。すなわち事前にaca-pyにそのエンドポイントを渡しておくWebhookになります。

Proof提示・検証でのProtocol

先ほどはCredentialの発行におけるProtocolの進む様子について説明しました。ここでは別の具体例として、HolderがProofを提示してVerifierが検証するためのAries RFC 0037: Present Proof Protocol 1.0における状態遷移を見ていきます。

Holder側の状態遷移です。
proposal_sent -> request_received -> presentation_sent -> presentation_acked

Verifier側の状態遷移です。
proposal_received -> request_sent -> presentation_received -> verified

上記は次のように読み替えられます。数字は処理順序です。

  1. 検証のproposalがHolderからVerifierへ送られる。
  2. Proof(Presentation)のrequestがVerifierからHolderへ送られる。
  3. ProofがHolderからVerifierへ送られる。
  4. VerifierはProofを受け取った事実をHolderに送り、検証を終わらす。

備考として、Holderのproposalからではなく、Verifierのproof requestからProtocolを開始することもできます。(今回のPoCではそうしています。)

各種フレームワーク

Ariesを実装するフレームワークは以下のように様々なものがあり、開発が進められている模様です。各フレームワークはそれぞれ特徴を持っており、前述したaca-pyはフレームワークとアプリが別プロセスになりますが、aries-framework-dotnetは、一般的なWebフレームワークと同じでアプリと1つのプロセスになって動作します。

また以下は上記フレームワークを使って開発が進められているモバイルアプリ型のHolder Agentです。(ここから言えることは、これらのフレームワークを使ってHolder Agentを自作することができると考えます。)

参考にした資料


以上が前編になります。
最後までお読みいただきありがとうございました。

後編はこちらからご覧ください。