Zero Knowledge SSO

この記事について Decentralized SSOはすっごく前に作った作品ですが、それにZK(Zero Knowledge Proof)を追加したプロトコルを作りました。 この記事では、そのプロコトル制作の背景やプロコトルについて書きます。 正直、プロトコルと言うほど崇高なものではないですが、便宜上そう言ってます。 Zero Knowledge SSOに行き着くまで 前まではZKの意義深さがよく分からずにスルーしていたのですが、今年(2024年)の7月にZKの重要性を理解しました。 これは回路を書いたりと手を動かしてみたことが大きいと思います。 ZKの数学は難しいのですが、有用なライブラリ多いため実際に手を動かす分には数学無しでも扱えるようになっています。 そこからアプリケーションでもっとZKが使われて欲しい!との思いから、数学なしでZKのアプリケーションを作るための記事を書いたりしていました。 さて、それが一段落したところで、ZKを使ってSSOできないかな、と思い立ちました。 というのも、以前に作っていたDecentralized SSOでの課題を解決できそうな気がしたためです。 Decentralized SSOでは複数のIdPからユーザの信頼情報を取得しますが、その際に複数のサービス間で同一のアイデンティティを利用するためアイデンティティが紐づくというプライバシー上の懸念がありました。 そこでZKを使うことで、ユーザの信頼情報のみを取得し、アイデンティティを紐付けないでSSOを実現できるのではないか、と考えました。 色々と調べていくうちに、Ethereum財団のPSE(Privacy and Scaling Explorations)がSemaphoreというアイデンティティ関連のライブラリを作っていたため、それを利用することにしました。 また、PSEがAcceleration Programというタスクにお金を払うプログラムをやっていたため、それに応募できそうだと思いました。 ということで、1週間程度で雑にプロトタイプと仕様を作り、それを提出しました。 PSEの人がレビューをした後、今ちょうどスマホの鍵管理アプリを作っているプロジェクトがあって、それと統合したらどうだろうか?と言われました。 スマホアプリで実際に実現が出来そうだったので、それに同意してそのプロジェクトが完了するのを待っている最中です(2024/10/07 現在)。 待ち続けて2ヶ月以上経つので、一旦アウトプットとして書いておきます。 なお、以下はEthResearchにも投稿した内容の日本語版です。 プロトコル 概要 Anoidenは、ゼロ知識証明を用いた匿名シングルサインオンプロトコルです。このプロトコルは、アイデンティティプロバイダー(IdP)とサービスプロバイダー(SP)が共謀しても、ユーザのアイデンティティを秘密に保ちながらIdPからの情報を使ってSPへのサインインを可能にします。これはSemaphoreライブラリを利用します。 Connect ユーザは、IdPが指定する方法(Eメールや電話番号の登録など)でアカウントを作成し、ゼロ知識証明の鍵と接続します。 Auth SPはIdPを信頼しており、認証のエンドポイントを知っています。ユーザはSPに対してIdPでのログインを要求し、ノンスを取得します。 その後、ユーザは自身のアイデンティティの証明を作成しIdPに送信します。IdPは証明を確認し、ユーザが正当であれば対応する署名を作成します。 用語 拡張機能: ブラウザ拡張機能(アプリでも可)で、ユーザの鍵管理や証明の作成等を行います。SPとIdPが結託してもアイデンティティが秘匿されるために必要です。 anoiden.js: ウェブサイトのクライアントに拡張機能と通信するためのインターフェイスを提供します。 アイデンティティプロバイダー(IdP): ユーザの正当性の情報をSPに提供する主体です。 サービスプロバイダー(SP): IdPから提供されるユーザの正当性を利用する主体です。 IdPへの登録(Connect) ユーザがIdPでアカウント登録を完了すると、そのアカウントと拡張機能側の鍵を連携できます。 この連携により、ユーザは今後、認証を要求された際にこのIdPを使用可能になります。 また、鍵を使って匿名でIdPにログインすることも可能になります。 IdPのクライアントはanoiden.jsを通じて、署名と公開鍵を取得します。 const {signature, publicKey} = await connect(serviceName, nonce); ここでserviceNameはIdPのサービス名で、鍵の管理に使用されます。 nonceは推測が不可能な文字列で、IdPのサーバサイドから取得します。 以下の図はIdPのクライアントがユーザの署名を取得するまでのフローです。 クライアントは取得した署名、公開鍵、ノンスをサーバに送信します。 サーバはセッションを確認し、そのユーザに対してそのノンスを発行したかを確認します。 有効であれば署名を検証し、identifier(公開鍵のposeidonハッシュ)を取得し、Merkle Treeにidentifierを追加し、追加後のMerkle Rootを保存します。 Authorize SPはIdPを利用する際、事前に利用することを伝えており、IdPからクライアントIDを受け取っていることとします。...

October 7, 2024

Decentralized SSO

Decentralized SSO Decentralized SSOは、SSOを分権化することで、セキュリティを向上させる仕組み・ブラウザ拡張のソフトウェアです。 この作品は私が普通科の高校生だった頃(2020の春頃)に制作し、U-22プロコンBest40の評価を頂いた処女作(Best40程度では処女作に入らないかもしれませんが)です。 U-22には、Aoiという作品名で提出しています。 背景 皆さまご存じの通り、SSO(Single Sign On)はその利便性から、広く普及しています。 しかし広い意味でのセキュリティ的な懸念があります。 つまり、SSOを提供する主体(Trusted Party)が絶対的な権威となり、利用者の正当性を保障するということです。 SSOを利用する主体(Relying Party)は利用者の正当性を根拠なく信じます。 この正当性というのは、利用者がBotでないこと、利用者が本人であること、利用者が正当な目的で利用していることなどです。 一つ例を挙げましょう。 TwitterはSSOを提供しています。 もしElonMuskが狂ってしまい、TwitterのSSOでなんらかの不正な認証が行われるとしたら? 世の中のサービスは大混乱です。 TrustedPartyが保障する利用者の正当性についての情報がより信頼できればRelying Party側はハッピーです。 では、どうすれば情報の信頼性が向上するのでしょうか? 解決策 複数のTrusted Partyから利用者の正当性に関する情報を得ることが出来れば、情報の信頼性を高めることができます。 これが大きな方針です。 Decentralized SSOでは、利用者のアカウントを公開鍵として表現します。 Decentralized SSOの利用プロセスはシンプルで、次のようなものです。 利用者は、Decentralized SSOを利用するTrusted Partyにアクセスし、会員登録を行う。 利用者は、Trusted Partyの内部アカウントと拡張機能のアカウントを紐づけます。 利用者は、この1~2を他のTrusted Partyでも同様に行います。ただし、拡張機能側のアカウントは1つです。 そして、とあるRelying Partyを利用し始めるとき、その公開鍵利用してログインできます。 Relying Partyは自分が比較的信頼する複数のTrustedPartyから、利用者の公開鍵のハッシュ値をもとにして利用者の正当性を確認します。 これだけです。 これだけで、SSOの信頼性が向上します。 公開鍵を利用するということがポイントですね。 この方法の問題点 ただしこれにはいくつかの問題点があります。 公開鍵とサービス内部のアカウントを紐づけることで、より多くのサービスに渡って利用者がプロファイリングされる。 統一された規格を利用する必要があるが、標準化のID( Internet Draft )提出などを行っていない。 ただし、Metamaskなどのブラウザウォレットの普及によって、2020年ほど普及のハードルは高くないと思います。 これらの問題点が解決されることを願いつつ、私は今日も自分の興味に従い他の領域に足を踏み入れます。 いつかこの作品にひょっこり戻ってくるかもしれません。

April 18, 2023