
パスキーはなぜフィッシングに強いのか ― WebAuthn / FIDO2 と公開鍵ログインの仕組み
パスキー(passkey)は、「パスワードを少し便利に保存する機能」ではありません。WebAuthn / FIDO2 に基づく 公開鍵認証であり、サーバーに再利用可能な秘密を渡さないログイン方式です。
特に重要なのは、フィッシング耐性です。ここでいうフィッシングは魚釣りではなく、偽ログイン画面にユーザーを誘導して認証情報を盗む攻撃のことです。パスキーでは、偽サイトに入力できるパスワードや6桁コードがそもそも存在しません。本記事では、なぜそれが成り立つのかを、WebAuthn の登録・認証フローから読み解きます。
パスワードは共有秘密、パスキーは公開鍵
従来のパスワード認証では、ユーザーが覚えた文字列をサーバーへ送ります。サーバーは平文ではなくハッシュ化して保存するのが基本ですが、それでも本質は「ユーザーが知っている秘密を、サーバー側も検証できる形で持つ」方式です。
パスキーでは、この前提が変わります。ユーザーの端末やセキュリティキーは秘密鍵を保持し、サービス側は対応する公開鍵を保存します。ログイン時にサーバーは使い捨てのチャレンジを出し、端末は秘密鍵で署名します。サーバーは公開鍵で署名を検証します。
パスワード:
user -> server: password
server: password hash と照合
パスキー:
server -> user: challenge
user device: challenge を秘密鍵で署名
user -> server: signature
server: 公開鍵で signature を検証
この違いは大きいです。パスワードは漏れるとそのまま再利用されます。パスキーでは、サーバーに保存される公開鍵が漏れても、それだけではログインできません。秘密鍵は端末側から出ない設計だからです。
WebAuthn Level 3は何を定義しているか
WebAuthn は、Webアプリが公開鍵Credentialを作成・利用するためのブラウザAPIです。W3C の WebAuthn Level 3 は 2026年5月26日に Candidate Recommendation Snapshot として公開されており、強い公開鍵CredentialをWebアプリが扱うためのAPI、Authenticator、Relying Party(RP)のモデルを定義しています。
WebAuthn の中心概念は、Relying Party、Authenticator、PublicKeyCredential です。
| 用語 | 意味 |
|---|---|
| Relying Party(RP) | ログインを受け付けるWebサービス。例: example.com |
| Authenticator | 秘密鍵を持つ装置。スマホ、PCのTPM、セキュリティキーなど |
| PublicKeyCredential | WebAuthnで作られる公開鍵ベースのCredential |
「パスキー」という言葉は、ユーザー向けの呼び方です。技術的には、WebAuthn Credential のうち、端末内やクラウド同期されたAuthenticatorで扱われる公開鍵Credentialとして理解すると見通しがよくなります。
登録時に起きること
パスキーの登録は、パスワードを決める操作とは違います。ユーザーが文字列を考えるのではなく、Authenticatorが新しい鍵ペアを作ります。
- サーバーがユーザーID、RP ID、チャレンジ、許可するアルゴリズムなどをブラウザへ渡す
- ブラウザが
navigator.credentials.create({ publicKey: ... })を呼ぶ - Authenticatorがユーザー確認を求める。例: 指紋、顔認証、端末PIN、セキュリティキーのタッチ
- Authenticatorが秘密鍵・公開鍵のペアを作る
- サーバーは公開鍵、credential ID、署名アルゴリズム、必要ならattestation情報を保存する
ここで秘密鍵はサーバーへ送られません。サーバーが受け取るのは、以後の署名検証に使う公開鍵です。これはパスワードデータベースの発想とは根本的に違います。
attestationは、Authenticatorの種類や特性をRPが評価するための仕組みです。企業や高保証の環境では意味がありますが、一般向けサービスではプライバシーや実装負荷との兼ね合いで、attestationを強く要求しない設計もあります。
ログイン時に起きること
ログイン時は、サーバーが「この場限りの問題」を出し、Authenticatorが秘密鍵で答えます。問題にあたるのがチャレンジです。
- ユーザーがログインを開始する
- サーバーがランダムなチャレンジと、許可するcredential情報を返す
- ブラウザが
navigator.credentials.get({ publicKey: ... })を呼ぶ - Authenticatorがユーザー確認またはユーザー存在確認を行う
- Authenticatorがチャレンジ、RP ID hash、フラグ、署名カウンターなどを含むデータに署名する
- サーバーが保存済み公開鍵で署名を検証する
チャレンジは毎回変わるため、過去のログイン応答を録音して再送しても通りません。NIST SP 800-63B も、nonceやchallengeを使うプロトコルをreplay-resistantな認証の例として扱っています。
ユーザーの視点では「指紋でログインした」ように見えますが、サーバーへ指紋画像が送られているわけではありません。生体認証やPINは、端末内の秘密鍵を使うためのローカルな解除操作です。
署名は何に対して行われるのか
WebAuthnのログイン応答は、単にチャレンジだけに署名しているわけではありません。大まかには、ブラウザが作る clientDataJSON と、Authenticatorが作る authenticatorData を組み合わせた内容が検証対象になります。
| データ | 含まれる主な情報 | 検証で見る理由 |
|---|---|---|
clientDataJSON | challenge、origin、typeなど | どのWeb originで、どの種類の操作として使われたかを見る |
authenticatorData | RP ID hash、flags、signature counterなど | Credentialが期待するRPに結びつくか、ユーザー確認が行われたかを見る |
サーバーは、署名が数学的に正しいかだけでなく、challenge が自分の発行したものか、origin が想定どおりか、RP ID hashが一致するか、必要なユーザー確認フラグが立っているかを確認します。この検証を省くと、WebAuthnを使っていても実装として弱くなります。
つまり、パスキーの強さは「秘密鍵で署名する」だけではなく、「ブラウザとAuthenticatorが、サイト名・チャレンジ・ユーザー操作をまとめて検証可能な形にする」点にあります。ここが、単なる暗号署名APIとは違うところです。
なぜフィッシングに強いのか
パスキーのフィッシング耐性は、「ユーザーが頑張ってURLを見分ける」ことに依存しません。NIST SP 800-63B は、フィッシング耐性を、偽のverifierへ認証秘密や有効な認証出力を渡させない能力として説明し、WebAuthn / FIDO2を verifier name binding の例に挙げています。
WebAuthnでは、CredentialはRP IDに結びつきます。たとえば example.com 用に作ったパスキーは、見た目だけを真似た examp1e.com では同じCredentialとして使えません。ブラウザとAuthenticatorが、ログイン先のorigin / RP IDを認証処理に含めるためです。
本物: https://example.com
credential for example.com -> 署名できる
偽物: https://examp1e.com
credential for example.com -> 使えない
MDNも、WebAuthnの利点として、偽ログインサイトを作った攻撃者は、署名がWebサイトのoriginで変わるためユーザーとしてログインできないと説明しています。パスワードやSMSコードのように「見た目が本物なら入力してしまう」秘密を持たない点が、パスキーの強さです。
TOTPやSMSコードとの違い
TOTPやSMSの6桁コードは、パスワードだけよりは強い二要素認証です。しかし、ユーザーがコードを目で見て入力する方式は、偽サイトがそのコードをリアルタイムで本物サイトへ中継する攻撃に弱い場合があります。
NIST SP 800-63B は、手入力されるAuthenticator出力は、出力が特定セッションに結びつかないためフィッシング耐性があるとは見なさない、と説明しています。偽サイトがコードを受け取り、本物サイトへ即座に渡せるからです。
| 方式 | サーバーへ渡すもの | フィッシング耐性 |
|---|---|---|
| パスワード | 再利用可能な秘密 | 弱い |
| TOTP / SMS | 短時間有効なコード | 中継攻撃に注意 |
| パスキー | origin / RP IDに結びついた署名 | 強い |
これはTOTPが無意味という話ではありません。パスワード単独より大きく安全です。ただし、フィッシング耐性という観点では、公開鍵Credentialをサイト名に結びつけるWebAuthnのほうが一段強い設計です。
同期パスキーと端末固定キー
パスキーには、大きく分けて同期されるCredentialと、端末やセキュリティキーに固定されるCredentialがあります。前者はスマホを買い替えても同じアカウントで復元しやすく、後者は秘密鍵の移動範囲が狭いぶん管理境界が読みやすい、という違いがあります。
| 種類 | 強み | 注意点 |
|---|---|---|
| 同期パスキー | 複数端末で使いやすい。復旧しやすい | クラウドアカウントの保護が重要 |
| 端末固定 / セキュリティキー | 高保証環境で境界を管理しやすい | 紛失時の復旧設計が必須 |
一般ユーザー向けサービスでは同期パスキーの使いやすさが大きな利点です。一方、管理者アカウント、金融、企業端末、規制産業では、セキュリティキーや端末管理、attestation、複数キー登録などを組み合わせる設計が向きます。
ユーザー名を入れないログインとdiscoverable credential
パスキーの体験で特徴的なのが、ユーザー名を先に入力しなくても候補が出るログインです。これは、Authenticator側でユーザーアカウント情報とCredentialを見つけられる discoverable credential の考え方と関係します。
従来の二要素認証では、まずユーザー名とパスワードを入力し、その後にコードやセキュリティキーを使う流れが一般的でした。パスキーでは、ブラウザやOSのCredential Managerが、現在のRP IDに合うCredential候補を提示し、ユーザーが選んで本人確認するだけでログインできます。
ただし、これもUI設計が重要です。共有PCで誰の候補が見えるのか、家族端末でアカウントを取り違えないか、会社端末で個人パスキーを使わせるのか、といった問題があります。便利さだけを優先すると、サポート問い合わせやアカウント混同の原因になります。
パスキーでも復旧設計は難しい
パスキーはログインを強くしますが、アカウント復旧まで自動で安全になるわけではありません。多くのアカウント侵害は、最強のログイン手段そのものではなく、弱い復旧経路から起きます。
たとえば、ログインはパスキー必須でも、復旧が「メールに届いた6桁コードだけ」で済むなら、攻撃者はメールアカウントを狙います。本人確認済み端末の追加、複数パスキー登録、バックアップコード、復旧用メールの再確認、サポート窓口の手順など、復旧フロー全体を設計する必要があります。
ユーザー向けには、最低でも次を案内したいところです。
- 重要アカウントには複数のパスキーを登録する
- スマホだけでなくPCやセキュリティキーも登録しておく
- クラウドアカウント自体に強い認証を設定する
- 復旧メールや電話番号を放置しない
実装で間違えやすいポイント
WebAuthnの安全性は、ブラウザやAuthenticatorだけで完結しません。RP側の実装にも落とし穴があります。
- challengeの使い回し: チャレンジは十分にランダムで、短時間だけ有効にし、検証後に破棄します。
- origin / RP ID検証の不足: 署名が正しくても、想定したoriginとRP IDで作られた応答か確認します。
- user verificationの扱い: 重要操作では
userVerification: "required"を検討します。 - credential IDの紐づけミス: どのユーザーのどの公開鍵かを厳密に管理します。
- 復旧フローの弱さ: パスキーを迂回できる経路が弱いと、全体として弱くなります。
また、パスキー導入直後は、ユーザーが「どの端末に登録したか」「同期されているのか」「会社端末でも使ってよいのか」を迷いやすいです。UI文言とヘルプは、暗号用語よりも「この端末で本人確認してログインする」「別端末にも追加できる」といった行動ベースで設計する必要があります。
パスキーは万能ではない
パスキーはフィッシング耐性を大きく高めますが、万能ではありません。端末がマルウェアに感染している場合、ログイン後のセッションを乗っ取られる可能性はあります。サーバー側の認可バグ、セッション固定、XSS、OAuth設定ミス、サポート窓口のなりすましも別問題です。
さらに、ユーザーが騙されて攻撃者の端末を自分のアカウントに追加してしまうようなフロー、リモートサポート詐欺、MDM管理外端末の混在など、人間と運用の問題も残ります。パスキーは「ログイン時に秘密を盗まれにくくする」技術であって、アカウント管理全体の設計を不要にするものではありません。
それでも、パスワードや手入力コードと比べると、攻撃者が偽サイトを用意して認証情報を吸い上げる典型的な攻撃の成功率を大きく下げられます。FIDO Allianceが、パスキーを公開鍵暗号に基づくフィッシング耐性のある認証として位置づける理由はここにあります。
まとめ ― 入力する秘密から、署名する端末へ
パスキーの本質は、ユーザーが秘密を入力する世界から、端末が秘密鍵で署名する世界への移行です。サーバーは秘密を受け取らず、公開鍵で検証します。ログイン先のorigin / RP IDに結びつくため、見た目だけ本物に似せた偽サイトでは同じCredentialを使えません。
実務では、パスキーを「便利なログインボタン」としてだけ見ないことが大切です。登録、認証、復旧、端末追加、管理者アカウント、サポート運用まで含めて設計して初めて、フィッシング耐性が活きます。
合言葉は単純です。パスワードは入力する秘密。TOTPは入力する短命コード。パスキーは、サイト名に結びついた秘密鍵で署名する認証。ここを区別できれば、パスキーがなぜ強いのか、どこに注意すべきかが見えてきます。
参考文献・ソース
記事作成に関する注記
本記事は AI(大規模言語モデル)を編集補助として活用して作成しています。 公開前に編集者が内容を確認していますが、事実誤認・仕様の解釈ミス・最新情報との齟齬が含まれる可能性があります。 重要な判断を行う際は、本文中の一次ソースや公式ドキュメントを必ずご自身でご確認ください。 誤りにお気づきの場合は、お問い合わせフォームよりご連絡いただけると助かります。


