🧘‍♂️

Q. OpenID Connectでパスキー相当の認証要素を実現する方法を考えてください

2024/01/04に公開

ritou です。

この記事はパスキーとOIDCの仕様がわかったつもりになったぐらいの人向けの頭の体操であり、実際にこれやれとかいう話ではありません。

問題

タイトルの通り、OIDCの仕組み+αでパスキーみたいなことやれんのかを考えてみましょう。

パスキー対応したOPにOIDCで連携する は一旦なしでええやろがい。

OpenID Connectの仕様はこちら。

https://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html

この仕様にあるあれがこれをやれば...ぐらいで、ある程度までいけそうです。

ヒント

これを実現するためにはパスキーで行われている処理を理解してOIDCで代替できるかを考えてみると良いでしょう。

  • Authenticator相当のIdP呼び出し
  • 呼び出し元のドメインなどの検証
  • ユーザー、サイトごとのPublicKey Credential
  • Attestation/Assertion
  • UserVerification

一番最初のところをイメージするのが大変ですかね。

答え

こんなところでしょう。

  • SIOPの仕組みを利用して端末上で動作するOP(モバイルアプリ)を呼び出す
  • ブラウザが仲介してドメイン検証などを行いフィッシング対策となる部分はこれだけだと難しい
  • RP情報とユーザー情報を鍵情報と一緒に保存する navigator.credentials.create() 相当の認証要求、それらを使う navigator.credentials.get() 相当の認証要求を内部で分けて扱う
  • WebAuthnでRPが指定するパラメータはlogin_hint, acr/amrとか既存のを頑張って使ってもいいし(RARはめんどくさいので)独自パラメータでもいいかも
  • OPは受け取ったユーザー/RP毎に鍵ペアを生成して、それらと一緒に管理することでDiscoverable Credentials相当を実現
  • UserVerificationに相当する部分はOPはローカル認証を呼び出してそれっぽく実現
  • Attestation/AssertionはIDTokenをもうちょいカスタマイズして表現
  • Autofillはちょっと無理そう

SIOP

そもそもSIOPってなんだよと言うところがあるでしょう。10年前の記事ですみません。

https://ritou.hatenablog.com/entry/20130718/1374107391

OS(PC, モバイル端末)やブラウザ内で動作し、openid://で呼び出される
ユニークなRSAやECDSAとかのprivate/publicな鍵ペアを生成して安全に管理する
クライアント(Webサービスやアプリ)からリクエストを受けたら署名付のID Tokenを返す

最近はVerifiable Credentials文脈でSIOP v2ってのが議論されていますが、それじゃなくてもっとレガシーな感じのやつです。実際に使われているのは...ずーっと前にリクルートがどうこうってのだけ聞いたことがあるぐらいですかね。

ざっくり言うと、OIDCの認証リクエスト、レスポンスでローカルのIdPを呼び出しましょうって感じのものです。
認証要求をローカルなIdPに送り、認証応答をもらえるよってのだけ定義されているので、そこから先をよしなに実装してしまえばパスキー認証に近いものが実現できるかもというお話です。

認証要素については、

  • ユーザーの端末内で生成、管理される鍵ペアの所有要素
  • ローカル認証による知識/生体要素

の組み合わせとなり、パスキー認証と同等です。

こんな感じで、それぞれの仕様の理解を深めて頭の体操ができるようになると楽しいですよ。
ではまた。

この記事書こうと思ったきっかけ:

https://twitter.com/nov/status/1737676697670238352

Discussion