所有している MacBook Pro と Surface Pro 4 は両方とも顔認証を使った Windows Hello を使うようにしているので、そろそろ Web サービス側も Windows Hello で便利になって欲しいです。
Build 2016 で発表されてから、特に話題に上ることもなくなってしまいましたが、実装してみたいので Web Authentication API (FIDO 2.0) について調べました。
私が調べた範囲では Windows Hello に対応した Web サービスを見たことがないので、今のうちに一通りの実装を試しておいて、どこかで組み込むチャンスが来るのを狙うという寸法です。
W3C による標準化
元々提案された FIDO 2.0 と Web Authentication API の現在のドラフトが公開されてます。
FIDO 2.0: Web API for accessing FIDO 2.0 credentials
Web Authentication: An API for accessing Scoped Credentials
概要をさっくりと掴むには ZDNet の翻訳記事が分かりやすかったと思います。
今でもまだワーキングドラフトのままなので、勧告候補になるまでまだ時間はかかりそうです。
ブラウザ側の対応
Edge は対応済みで、Chrome と Firefox は開発中らしい。Safari は期待するだけ無駄な気がする。
とはいえ、まだ Web Authentication API 自体の仕様が固まってないので、特に Edge に関しては polyfill を使って対応するのが、今のところはベスト。
技術的な説明
Edge に実装されている msCredential が Web Authentication API とは大きく異なっているので、ちゃんと polyfill を使って後で苦労しないようにしましょう。
マイクロソフトの松崎さんが貴重な日本語解説を書いてくれています。
英語ですが Microsoft Edge のドキュメントには Web Authentication API についての説明があります。
Web Authentication API 自体は結構シンプルなので、後は対応したデバイスがあれば実装が出来そうです。現時点では Edge と Windows Hello 対応デバイスが必須です。
Web Authn API での認証の流れ
Web Authentication API では基本的には公開鍵暗号を使って認証を行います。したがって、まずサービス側に公開鍵を登録するという作業が必要です。
登録時には鍵ペアを作成し、ログイン時には署名を生成することになります。それぞれ makeCredential と getAssertion メソッドが直接対応しています。登録時には makeCredential を使って鍵ペアを作成し、公開鍵をサービス側に渡します。
サービス側では makeCredential に id を渡すか、実行結果に含まれている id を使ってユーザーの識別を行います。基本はこの id と公開鍵を使ってユーザーを認証します。
ログイン時にはサービスから Challenge として文字列を受け取り、getAssertion に渡して署名を作成します。
サービス側はその署名を受け取り、Challenge と公開鍵を使って検証を行います。検証が通れば対応する秘密鍵を持っていることが確定するので、実際にログイン処理を行って完了です。大雑把ですがこんな感じです。
検索して見つかったサンプルコードは、実際に組み込んで使えるようなレベルではなかったので、ASP.NET Identity に Windows Hello でのログイン機能を実際に追加して検証しました。コードの整理が完了したら、どのように実装したかをまた書こうと思います。