Web Authentication API の裏側と、なぜそうなっているのかを図解した


次世代 Web 認証仕様 Web Authentication API (以下 WebAuthn) が、今年の4月に勧告候補となりました。

が、ブラウザで利用するインターフェースは navigator.credentials.create()navigator.credentials.get() の2つのみなので、それ以外の実装については MDN のドキュメントを読んだり、W3C Specification を読んだりして理解する必要があると思います。

ただ、分量のある仕様を読み解くのは大変です。また、仕様は往々にして、「こうすべき(手段)」が書かれているのみで、「なぜこうすべきか(根拠)」は書かれていない、あるいは分かりにくいことがあります。

そこで、勉強がてらですが Yubico の Luke Walker さんの資料を参考に、WebAuthn の裏側である FIDO の登録フロー、認証フローをそれぞれ図解してみました。

FIDO 登録フロー

FIDO では、よく Authenticator、Client、Relying Party という登場人物が現れます。
WebAuthn で言うと、Authenticator は鍵ペアを保持する認証デバイス、Client は Web ブラウザ、Relying Party は認証を必要とする Web サービスの提供者となります。

WebAuthn は、「Authenticator と Client 間のやりとりを Web ブラウザが代替してくれる、そのための標準仕様」という理解をしています。
なので、WebAuthn を認証方法の一つとして利用したいサービス提供者が意識するのは、Client と Relying Party 間のやりとりです。

まず、ユーザがサービスに登録する際のフローです。
単に公開鍵暗号方式でパスワードレスを実現しているだけでなく、フィッシング攻撃やリプレイ攻撃、Authenticator の偽装などを防ぐように設計されていることが分かります。

FIDO 認証フロー

次に、登録済みのユーザがサービスにログインする際のフローです。
登録時に Relying Party に保存した公開鍵を使って、Authenticator から送られる署名を検証することでログインしますが、それ以外にも、登録フロー同様にフィッシング攻撃やリプレイ攻撃を防ぐためのパラメータや検証が必要となります。