はじめに
2022年12月に Chrome でパスキーが利用できるようになりました。
そのことを伝えるネット記事をいくつか読んだときには、パスキーを使った認証の全体像というか仕組みというかそういうものがいまいちピンと来なかったので、もう少し詳しいことを調べつつデモサイトでその動作を体験してみました。
WebAuthn とパスキー
WebAuthn (Web Authentication)
WebAuthn は認証に関するウェブ標準の1つで、いわゆる「パスワード不要の認証」を実現する FIDO2 認証をウェブブラウザ上で実現するためのものです。
従来のIDとパスワードによる認証では、パスワード(あるいはパスワードのハッシュ)という秘密情報をサービスのサーバに預ける必要がありました。そのため漏洩のリスクがあり、漏洩してしまうと同じパスワードを使う別のサービスでも使われてしまうという問題を抱えています。
WebAuthn による認証は次のような特徴を持っています。
- 秘密情報はユーザの手元のデバイスで保持する(漏洩のリスクが非常に低い)
- 認証に使うクレデンシャルはサービスのドメインと紐付けられているのでフィッシングに強い
- 従来型のログインで必要だったID・パスワードの入力や、ワンタイムパスワードの入力などが不要で、利便性が高い
WebAuthn によるユーザ登録の大まかな流れは以下の通りです。
- ウェブブラウザがサーバにユーザIDを送り、登録を要求する
- サーバがチャレンジ(検証に利用するランダムな数値列)を生成してブラウザに返す
- ブラウザは認証器にチャレンジを渡す
- 認証器は鍵ペアの生成承認を得るために、ユーザに生体認証を求める
- 生体認証がOKならば、認証器は秘密鍵と公開鍵のペアを生成する
- 認証器は秘密鍵を使ってチャレンジに署名し、署名付チャレンジ・公開鍵・クレデンシャルID(秘密鍵に紐付いたID)をウェブブラウザに返す
- ウェブブラウザは署名付チャレンジ・公開鍵・クレデンシャルIDをサーバに送る
- サーバは公開鍵を使って署名付チャレンジを検証する
- チャレンジの検証結果とその他のチェック(ドメインなど)がOKならユーザの公開鍵・クレデンシャルIDをユーザIDに対応付けて保存する
WebAuthn による認証の大まかな流れは以下の通りです。
- ウェブブラウザがサーバにユーザIDを送り、チャレンジを要求する
- サーバはユーザIDに紐付いたクレデンシャルIDと共にチャレンジをブラウザに返す
- ブラウザは認証器にチャレンジ・クレデンシャルIDを渡す
- 認証器は秘密鍵の利用承認を得るために、ユーザに生体認証を求める
- 生体認証がOKならば、認証器はクレデンシャルIDに対応した秘密鍵を使ってチャレンジに署名してウェブブラウザに返す
- ウェブブラウザは署名付チャレンジ・クレデンシャルIDをサーバに返す
- サーバは公開鍵を使って署名付チャレンジを検証する
- チャレンジの検証結果とその他のチェック(ドメインなど)がOKならログイン成功
重要なのは以下の点です。
- 秘密鍵はサーバに送られず、ローカルの認証器に保存される
- 生体認証の情報はサーバに送られず、ローカルの認証器で秘密鍵を利用するときのユーザ確認として利用される
重要な情報はローカルに有り、サーバ側で保存している情報(公開鍵やクレデンシャルID)が漏れたとしても攻撃には利用できない訳です。
パスキー
WebAuthn では基本的にウェブブラウザと認証器は同じ機器で動いていることが想定されていました(スマートフォン内蔵の指紋認証や PC の USB ポートに接続されたセキュリティキーなど)。スマートフォンで WebAuthn のクレデンシャルを生成し、記録したとします。買い替えや紛失でそのスマートフォンが使えなくなったら登録をやり直さなければなりません。また、異なる端末からログインする場合には同じサービスであってもそれぞれの端末で登録する必要がありました。
パスキーは WebAuthn のそういった課題を解決して使い勝手を向上させるための拡張です。
- ウェブブラウザと認証器が別々の機器であっても動くようにした
- 複数の認証器でクレデンシャルを同期できるようにした
パスキーによる認証を体験する
https://webauthn.io/ というデモサイトでパスキーによる認証を体験してみます。
登録
ユーザ名を入力して”Register”を押します。
今回はスマートフォンを利用するので「別のデバイス」を選びます。
QR コードが表示されるのでスマートフォンで読み込んで FIDO: で始まる URL にアクセスします。
パスキーの作成について確認されるので「続行」します。
スマートフォン側で生体認証を要求されます。(この画面はスクリーンショットを撮れませんでした)
ここで「このパソコンの情報を保持する」にチェックを入れておくと、認証の際に QR コードの表示(PC側)と読み取り(スマートフォン側)のステップをスキップできます。
これで登録完了です。
認証
登録済のユーザ名を入力して”Authenticate”を押します。
先程登録に使ったスマートフォンを選びます。
スマートフォン側で生体認証を要求されます。(この画面はスクリーンショットを撮れませんでした)
ログイン完了。一旦登録が完了してしまえばログインは非常に簡単です。
ここまでの手順は Linux デスクトップで行いました。
Chrome でパスキーが使えるようになったというリリース情報では Linux 版の Chrome が対応しているのかどうかいまいちハッキリしないところがあったのですが、試してみるとあっさり動きました。
この状態で、たとえば別の Windows PC の Chrome で webauthn.io にアクセスしてスマートフォンを認証器として利用して splout01 で同じ手順でログインできます。
パスキーを利用する際に Bluetooth を使って機器同士の近接をチェックしているので、PC とスマートフォンの両方で Bluetooth が有効になっていないといけません。試しに PC とスマートフォンそれぞれで Bluetooth をオフにしたところ、どちらがオフの場合でも途中で認証失敗となりました。(Bluetooth をオンにするように促される)
おわりに
従来よりも安全でパスワードの煩わしさからも解放されるパスキーには大いに期待しています。
これから対応サービスが増えていくのが楽しみです。