AIかも!Tech Lab - 開発のリアル

パスキーはなぜフィッシングに強いのか──WebAuthnの仕組みとクラウド同期の守り方

前編「相次ぐ個人情報漏洩、利用者の側でできる3つの備え」では、一般の利用者にパスキーを勧めました。理由は「偽サイトに強いから」。本稿では、その根拠を技術者向けに掘り下げます。

WebAuthnの登録と認証、フィッシング耐性の根拠、Google パスワード マネージャー(以下GPM)の同期と復旧を順に見た後、2026年8月に公表された攻撃研究から、仕組みの限界と実装上の注意点を確認します。登録と認証は2026年8月25日にW3C勧告となったWeb Authentication Level 3に、同期と復旧はGoogleの公開資料に基づいて説明します。[1]

1 3つの登場人物と鍵ペア

パスキーによるログインには、3者が関わります。

  • RP(Relying Party):ログイン先のサービス。公開鍵を保存し、署名を検証する。図では「サービス側」と表記。
  • クライアント:ブラウザ。RPと認証器の間を取り持ち、RPが指定した識別子と実際に開いているサイトが合っているかを検査する。
  • 認証器(Authenticator):鍵ペアを生成し、秘密鍵で署名する。OSに組み込まれた機能、GPMのようなパスワードマネージャー、USBやNFCで接続するセキュリティキーなどが該当する。

扱う鍵は、通常の公開鍵暗号の鍵ペアです。秘密鍵は認証器の管理下にとどまり、RPには公開鍵だけを登録します。RPのデータベースから公開鍵が漏れても、それを使ってログインすることはできません。漏洩すればオフラインで総当たりされうるパスワードのハッシュとは、性質がまったく違います。

ログイン時に求められる指紋や顔、PINは、操作しているのが正当な利用者であることを認証器が確かめる「ユーザー検証(User Verification、UV)」に使われます(図では「本人確認」と表記)。指紋や顔による照合は端末内で完結し、生体情報がRPに送られることはありません。[2]

2 登録:RP IDと公開鍵を結びつける

https://shop.example.com で、既存のアカウントにパスキーを追加する場面を例にします。登録は、パスワードなど既存の方法でログイン済みのセッションから始めます。

RPは、navigator.credentials.create() に渡すオプションとして、主に次の値を用意します。[3]

  • RP ID:鍵の利用範囲を決める識別子。ドメイン名を使い、ここでは shop.example.com とする。
  • ユーザー情報:ユーザーIDと表示名など。
  • チャレンジ:この回の処理に固有のランダム値。返ってきた応答が、自分の始めた処理に対するものかを照合するために使う。
  • 認証器への要求:residentKey(パスキー、つまり発見可能なクレデンシャルとして作るか)や userVerification(ユーザー検証を必須とするか)など。

正規サイトの登録要求をブラウザが検査し、認証器が本人確認を経て鍵ペアを生成してRP IDと対応づけ、公開鍵をサービス側がアカウントに保存する流れ

ブラウザはまず、RP IDが現在のオリジンで使えるものかを検査します。RP IDは、オリジンのホスト名と同じか、その親ドメインでなければなりません(com のような公開サフィックスは不可)。shop.example.com なら、shop.example.com と example.com が使えます。[1] 検査を通ると、認証器がユーザー検証を経て鍵ペアを生成し、RP IDと結びつけて秘密鍵を保存します。

RPに返る応答には、ブラウザが作る clientDataJSON(処理の種類、チャレンジ、オリジン)と、認証器が作る認証器データ(authenticatorData。RP IDのハッシュ、フラグ、クレデンシャルID、公開鍵)が含まれます。RPはチャレンジ、オリジン、RP IDのハッシュ、UVフラグを検証したうえで、クレデンシャルIDと公開鍵をアカウントに保存します。[4]

この時点で、「どのサイトの、どのアカウントの、どの鍵か」という対応関係が確定します。この後の認証はすべて、この対応関係を確かめる作業です。

3 認証:秘密鍵を渡さずに証明する

ログインでは、RPが新しいチャレンジを発行し、ブラウザで navigator.credentials.get() を呼び出します。

サービスがチャレンジとRP IDを提示し、ブラウザが検査したうえで認証器が対応する鍵を選んで署名し、サービスが公開鍵で署名とチャレンジ、サイト情報を検証するログインの流れ

ブラウザは登録時と同じくRP IDを検査し、認証器に署名を依頼します。認証器はそのRP IDに対応する鍵を選び、ユーザー検証を経て、認証器データ(RP IDのハッシュ、フラグ、署名カウンタ)と clientDataJSON のハッシュを連結したものに署名します。[5]

RPに届くのは、署名と、署名の対象になったデータ、クレデンシャルIDなどです。秘密鍵そのものが送られることはありません。RPは保存済みの公開鍵で署名を検証し、あわせて主に次の点を確認します。[6]

  • クレデンシャルが、ログインしようとしているアカウントに登録されたものか
  • チャレンジが今回発行したものと一致するか(過去の応答の再利用を防ぐ)
  • clientDataJSON の種類が認証(webauthn.get)で、オリジンが自サービスのものか
  • RP IDのハッシュが一致するか
  • UP(ユーザーの操作)とUVのフラグが立っているか

4 フィッシング耐性はどこで担保されているか

正規サイトを shop.example.com、偽サイトを shop-login.example.net とします。画面がまったく同じでも、ブラウザから見れば別のオリジンです。

偽サイトを開いた場面で、パスワードは攻撃者が取得して正規サイトで使い、ワンタイムコードは中継されると有効な間は認証を通る場合があるが、パスキーは正規サイト用の鍵を偽ドメインで使えず有効な応答を作れない

パスワードもワンタイムコードも、「知っていれば使える」値です。偽サイトに入力された時点で攻撃者の手に渡り、正規サイトへ中継されれば、コードの有効期限内なら認証を通ってしまいます。入力された文字列には、利用者がどのサイトで入力したかという情報が含まれていないからです。[7]

パスキーでは、この中継が成立しません。

  1. 偽サイトが正規サイトのRP ID(shop.example.com)を指定すると、オリジンと合わないため、ブラウザが要求を拒否する。
  2. 偽サイトが自分のドメインをRP IDに指定しても、そのRP IDに対応する鍵は存在しない。
  3. さらにRP側でも、署名対象の clientDataJSON に記録されたオリジンを検証する。

要するに、「今どのサイトを開いているか」の判定を、利用者の目ではなく、ブラウザとRPが機械的に行っているのです。これがフィッシング耐性の正体です。[1]

なお、1つのサービスが複数のドメインを使う場合に備えて、Level 3では関連オリジン(Related Origin Requests)の仕組みが定義されています。RP IDのドメインの /.well-known/webauthn に許可するオリジンを列挙しておくと、別ドメインからでも同じRP IDの鍵を使えます。一覧を配信するのはRP IDのドメイン側なので、偽サイトが自分を一覧に加えることはできません。ブラウザによって対応状況が異なる点には注意が必要です。[1]

5 同期型パスキーはなぜ生まれたか

FIDO2が普及し始めた当初、鍵は1台の機器に固定する「デバイス固定型」が中心でした。安全性は高い一方、その機器を失えばログインできず、予備を持つにはサービスごとに2台目の機器を登録しておく必要がありました。[8] この復旧の負担を減らすため、FIDO Allianceは2022年3月、複数の端末で同じ認証情報を使えるマルチデバイス対応の構想を公表します。[9]

こうして、デバイス固定型に同期型が加わりました。デバイス固定型がなくなったわけではなく、セキュリティキーなどで今も使われています。[10]

RPは、認証器データのフラグからパスキーの性質を知ることができます。BE(Backup Eligibility)は、同期やバックアップの対象になりうる鍵かどうかを示し、作成後は変わりません。BS(Backup State)は、現時点で実際にバックアップされているかを示し、変わることがあります。[1]

同期型は、端末を失っても鍵が残るという利点と引き換えに、安全性の一部を、同期を担う事業者のアカウント保護と復旧手順に委ねることになります。

6 GPMは同期した鍵をどう守るか

GoogleはGPMのパスキーについて、エンドツーエンド暗号化(E2EE)で同期され、Googleを含め誰もアクセスできないと説明しています。[11]

ここでは、2種類の鍵を区別する必要があります。認証で署名に使う秘密鍵と、その秘密鍵を暗号化して保管するための保管用の暗号化鍵(以下、保管用の鍵)です。クラウドに置かれるのは暗号化された秘密鍵だけで、署名に使うには、保管用の鍵で復号しなければなりません。

署名用の秘密鍵を保管用の暗号化鍵で暗号化してクラウドに保管し、新しい環境ではGoogleアカウントへのログインと、GPMのPINまたは既存Android端末の画面ロックによる確認を経て復号し、認証に使う

新しい端末でパスキーを使い始めるときは、まずGoogleアカウントにログインして、どの利用者の同期データかを特定します。次に、GPMのPINか、以前から使っているAndroid端末の画面ロックを入力し、保管用の鍵を使える状態にします。PINは、Android以外の環境でも同期パスキーを使えるようにするため、2024年9月に導入されたものです。[12][13]

図は、端末上で復号して署名する場合の概念図です。Unit 42の報告によれば、パソコン版のChromeでは、秘密鍵はGoogleのクラウド上の隔離環境(エンクレーブ)で生成・使用され、端末はTPMなどで保護された鍵(端末の識別用の鍵と、ユーザー検証用の鍵)で、クラウド上の認証器に署名を依頼します。AndroidとiOSのGPMは、このクラウド上の認証器を使いません。[14]

Googleが2022年に公表した復旧の設計

保管用の鍵の扱いについては、Googleが2022年にAndroid向けの設計を公表しています。[15]

  • 保管用の鍵は、利用者の端末上でしか使えない。
  • 新しいAndroid端末へ移るときは、既存の端末から保管用の鍵を安全に転送する。
  • 既存の端末を失った場合は、保護されたオンラインバックアップから復旧する。それには、Googleアカウントへのログインと、以前の端末の画面ロックが必要になる。

画面ロックのPINは桁数が少なく、総当たりに弱そうに見えます。そこでこの設計では、Googleのサーバー上にある保護されたハードウェア(secure hardware enclave)が検証と試行回数の管理を担い、試行を最大10回に制限しています。このデータは、Googleを含め誰も読み出せないとされています。[15]

暗号化したデータを守るだけでなく、「保管用の鍵を取り戻す手順」そのものを総当たりから守っている。ここが設計の要です。なお、これは2022年時点の公開設計であり、その後、前述のPINの導入などの変更が加わっています。

7 仕組みの限界:端末が侵害されていたら

ここまでの防御は、主にネットワーク越しに攻撃してくる相手を想定しています。では、利用者の端末そのものが侵害されていたらどうなるのでしょうか。

2026年8月3日、Palo Alto NetworksのUnit 42は、GPMの同期パスキーに対する3種類の攻撃手法を「Pass the Passkey」として公表しました。前提は、TPMを搭載したWindows上のChromeで、すでにマルウェアが動いていることです。検証の対象はこの環境のGPMに限られ、前章で触れたとおり、AndroidとiOSのGPMは別の設計です。[14]

報告された手法は、次の3つです。

  • Pass-ta-key:端末の識別用の鍵を一般権限のプロセスから使い、クラウド上の認証器から、UVフラグの立っていない署名を得る。権限昇格、画面ロックの解除、利用者の操作は不要とされる。UVフラグを検査しないRPでは、これだけでログインが通る。
  • Silver Pass-ta-key:端末の再登録を誘発し、攻撃者が管理するユーザー検証用の鍵を、クラウド上の認証器に登録させる。新しく登録される鍵の構成証明(attestation)を検証していなかったことが原因とされる。以降は攻撃者自身の環境から、繰り返しUVフラグ付きの署名を得られる。端末の登録を解除するか、登録し直せば無効にできる。
  • Golden Pass-ta-key:保管用の鍵(報告では security domain secret)を取り出し、同期されたパスキーを復号する。この鍵は当初Chromeのログに平文で出力されていた。報告後にログからは削除されたが、プロセスのメモリからは引き続き取り出せるとされる。報告時点ではこの鍵を失効・更新する手段がなく、これから作るパスキーも同じ鍵で保護される。

Unit 42自身も、これらの攻撃はパスキーの暗号を破るものではなく、パスキーは認証の安全性を意味のある形で前進させると述べています。フィッシング耐性が崩れたわけでもありません。[14]

この研究が示したのは、「端末が侵害されたら何でも起きる」という一般論ではありません。端末の侵害を入口に、新しい鍵を登録するときの検証の欠落や、失効できないマスター鍵をクライアントに渡す設計など、同期の設計と実装の隙を突くと、攻撃者は再利用できるアクセス手段を得られる、という点です。原典は、この状態を「設計の前提と実装の隙」と表現しています。Googleの対応状況は、最新の公式情報を確認してください。

パスキーを実装する側にとっては、具体的な教訓があります。[14]

  • userVerification: "required" を指定するだけでなく、応答のUVフラグを必ず検査する。報告では、"required" を指定しながらUVなしの応答を受け入れていた実サービス(eBay。報告後に修正済み)が見つかっている。
  • 同期パスキーは署名カウンタが一定のままであることが多く、クローン検知の手がかりになりにくい。ログインの異常検知は、ほかの手段で補う。

8 スマートフォンをなくしたら

同期した鍵を新しい端末で取り戻すには、性質の違う2つの手段が必要になります。

目的 必要なもの
Googleアカウントに再びログインする 別の登録済み端末、予備のセキュリティキー、バックアップコードなど
同期されたパスキーを使える状態にする GPMのPIN、または以前から使っているAndroid端末の画面ロック

バックアップコードはGoogleアカウントの2段階認証プロセスで使う予備の手段で、パスキーの保護を解くことには使えません。[16][17] 前編で「2つを別々に用意する」と書いたのは、このためです。

GPMのPINを忘れた場合は、以前GPMを使ったことのある、Android以外の端末(パソコンなど)からPINを再設定できます。どの端末からも復元できずにパスキーのリセットを選ぶと、保存されていたパスキーはすべて削除され、サービスごとに作り直すことになります。[18]

9 まとめ:仕組みから導かれるチェックポイント

ここまでの内容から、実装する側と使う側それぞれの主な確認点をまとめます。

立場 確認すること
実装する側 第3章で挙げた項目(チャレンジ、オリジン、RP IDのハッシュ、UVフラグなど)を検証しているか。UVは指定するだけでなく、応答で検査しているか。
実装する側 パスキーが追加されたら利用者に通知し、一覧で確認・削除できるようにしているか。
実装する側 パスワードやSMSなど、フィッシングに弱いログイン手段が抜け道として残っていないか。
使う側 心当たりのないパスキーが登録されていないか。アカウントを奪った相手が自分の鍵を登録すれば、その鍵もログインに使える。
使う側 パスキーでのログイン中に、パスワード入力など別の方法へ誘導されたら、入力を止めて公式サイトを開き直す。
使う側 保管先のアカウントに戻る手段と、GPMのPINを別々に用意しているか。

パスキーへの移行は、利用者に「偽サイトを見抜け」と求め続けてきた認証の設計を、仕組みの側で引き受け直す試みだと言えます。その効果を引き出せるかどうかは、RPの検証の厳密さ、フォールバックの手段をどこまで絞れるか、そして同期を担う事業者の設計にかかっています。

利用者向けの設定手順や漏洩後の対処は、前編「相次ぐ個人情報漏洩、利用者の側でできる3つの備え」をご覧ください。

出典と公式手順

登録と認証は共通仕様と開発者向け資料、同期と復旧はGoogleの公開資料、攻撃研究はUnit 42の報告を参照しています。

  1. W3C:Web Authentication: An API for accessing Public Key Credentials Level 3(W3C勧告、2026年8月25日)
  2. Googleアカウントヘルプ:パスワードの代わりにパスキーでログインする
  3. web.dev:Create a passkey for passwordless logins
  4. Google for Developers:Server-side passkey registration
  5. web.dev:Sign in with a passkey through form autofill
  6. Google for Developers:Server-side passkey authentication
  7. FIDO Alliance:Displace Password + OTP Authentication with Passkeys(2024年)
  8. FIDO Alliance:FIDO Authentication for Moderate Assurance Use Cases(2024年)
  9. FIDO Alliance:Multi-Device FIDO Credentials(2022年3月17日)
  10. FIDO Alliance:Passkeys
  11. Chrome for Developers:パソコンとAndroid間でGoogle パスワード マネージャーのパスキーを同期(2024年)
  12. Google for Developers:Passkey support on Android and Chrome
  13. Google:Sync passkeys securely across your devices(2024年9月19日)
  14. Unit 42(Palo Alto Networks):Pass the Passkey: A Novel Attack Surface in Passwordless Authentication(2026年8月3日)
  15. Google Security Blog:Security of Passkeys in the Google Password Manager(2022年10月12日)
  16. Googleアカウントヘルプ:2段階認証プロセスに関する一般的な問題を解決する
  17. Googleアカウントヘルプ:バックアップコードを使用してログインする
  18. Google Chromeヘルプ:Google パスワード マネージャーのPINを管理する