FIDO2 認証(パスキー)の仕組み — パスワードを「構造的に不要にする」技術

サイボウズのバグバウンティで複数年度 1 位の実績を持つセキュリティ研究者 @yousukezan さんのポストで紹介されていた、FIDO2 認証(パスキー)の概要記事を深掘りします。元記事は Nagano さんの Zenn 記事です。

2026 年現在、日本証券業協会がパスキー(FIDO2)の導入を必須化するガイドラインを施行し、楽天証券・SMBC 日興証券などが相次いで導入を進めています。パスキーはもはや「新しい技術」ではなく「必須のインフラ」になりつつあります。

パスワード認証の根本的な問題

パスワード認証には、仕組みそのものに起因する構造的な脆弱性があります。

graph LR
    USER["ユーザー"] -->|パスワードを送信| SERVER["サーバー"]
    ATTACKER["攻撃者"] -.->|盗聴・フィッシング| USER

    style USER fill:#3498db,color:#fff
    style SERVER fill:#2ecc71,color:#fff
    style ATTACKER fill:#e74c3c,color:#fff
脅威内容
フィッシング偽サイトにパスワードを入力させる
リスト型攻撃漏洩したパスワードを他サービスで試行
中間者攻撃通信を傍受してパスワードを盗む
サーバー侵害サーバーに保存されたパスワードハッシュの漏洩

これらの問題は「秘密情報(パスワード)をネットワーク経由で送信する」という設計そのものに起因します。ワンタイムパスワード(OTP)でも、この根本構造は変わりません。実際、日本証券業協会は 2025 年 10 月のガイドライン改正で、OTP の利用を非推奨としています。

FIDO2 の設計思想 — 「秘密を送らない」

FIDO2 は発想を根本から変えました。秘密情報をネットワーク上に一切流さない認証方式です。

graph LR
    subgraph デバイス側
        USER2["ユーザー"] -->|生体認証/PIN| AUTH["認証器<br/>(TPM等)"]
        AUTH -->|秘密鍵で署名| SIGNED["署名データ"]
    end

    subgraph サーバー側
        SIGNED -->|署名のみ送信| VERIFY["公開鍵で検証"]
    end

    style USER2 fill:#3498db,color:#fff
    style AUTH fill:#f39c12,color:#fff
    style SIGNED fill:#9b59b6,color:#fff
    style VERIFY fill:#2ecc71,color:#fff

パスワード認証では「秘密そのもの」を送信しますが、FIDO2 では「秘密鍵で作った署名」だけを送信します。秘密鍵はデバイス内の安全な領域(TPM、Secure Enclave 等)に保管され、外部に出ることはありません。

FIDO2 のアーキテクチャ

FIDO2 は 2 つのプロトコルで構成されています。

graph TD
    subgraph FIDO2["FIDO2 フレームワーク"]
        WEBAUTHN["WebAuthn<br/>(W3C 標準 API)"]
        CTAP2["CTAP2<br/>(認証器プロトコル)"]
    end

    RP["Relying Party<br/>(サービス提供者)"] <-->|WebAuthn API| BROWSER["ブラウザ"]
    BROWSER <-->|CTAP2| AUTHENTICATOR["認証器<br/>(指紋/顔/セキュリティキー)"]

    style WEBAUTHN fill:#3498db,color:#fff
    style CTAP2 fill:#e67e22,color:#fff
    style RP fill:#2ecc71,color:#fff
    style BROWSER fill:#95a5a6,color:#fff
    style AUTHENTICATOR fill:#f39c12,color:#fff
プロトコル役割通信区間
WebAuthnブラウザとサーバー間の認証 API(W3C 標準)ブラウザ - サーバー
CTAP2認証器とブラウザ間の通信プロトコル認証器 - ブラウザ
  • WebAuthn は Web アプリケーションが公開鍵認証情報を作成・使用するための JavaScript API です
  • CTAP2(Client to Authenticator Protocol 2)は、USB・NFC・Bluetooth 経由で認証器と通信するためのプロトコルです

登録フロー — 公開鍵ペアの生成

パスキーの登録は以下の流れで行われます。

sequenceDiagram
    participant U as ユーザー
    participant A as 認証器(TPM等)
    participant B as ブラウザ
    participant S as サーバー

    U->>S: アカウント登録を開始
    S->>B: チャレンジ + RP情報を送信
    B->>A: 認証要求(ドメイン情報付き)
    A->>U: 生体認証/PINを要求
    U->>A: 指紋/顔/PINで本人確認
    A->>A: ドメイン固有の鍵ペアを生成
    A->>B: 公開鍵 + 署名付きデータ
    B->>S: 公開鍵を送信
    S->>S: 公開鍵を保存

重要なポイントは以下の通りです。

  • 秘密鍵はデバイスの外に出ない: TPM(Trusted Platform Module)や Secure Enclave 内で生成・保管されます
  • 鍵はドメインに紐づく: example.com で生成された鍵は evil.com では使えません。これがフィッシング耐性の根拠です
  • 公開鍵のみサーバーに保存: サーバーが侵害されても、公開鍵だけでは認証を突破できません

認証フロー — チャレンジ・レスポンス

登録後の認証は以下のように行われます。

sequenceDiagram
    participant U as ユーザー
    participant A as 認証器
    participant B as ブラウザ
    participant S as サーバー

    U->>S: ログイン要求
    S->>B: チャレンジ(ランダムな値)を送信
    B->>A: チャレンジ + ドメイン情報
    A->>A: ドメインを検証
    A->>U: 生体認証/PINを要求
    U->>A: 本人確認
    A->>A: 秘密鍵でチャレンジに署名
    A->>B: アサーション(署名データ)
    B->>S: アサーションを送信
    S->>S: 公開鍵で署名を検証
    S->>U: 認証成功

サーバーが送る「チャレンジ」は毎回異なるランダムな値です。これに秘密鍵で署名を行い、サーバーが公開鍵で検証します。署名データを傍受しても、別のチャレンジには使えないため、リプレイ攻撃が構造的に不可能です。

3 層のフィッシング防御

FIDO2 がフィッシングに対して「構造的に」強い理由は、3 つの層で防御しているためです。

graph TD
    PHISHING["フィッシングサイト<br/>evil.com"] -->|1. ブラウザが検出| BLOCK1["ブラウザがドメイン情報を<br/>認証器に正確に伝達"]
    BLOCK1 -->|2. 認証器が拒否| BLOCK2["evil.com 用の鍵は存在しない<br/>→ 認証不可"]
    BLOCK2 -->|3. サーバーが検証| BLOCK3["署名データ内のドメイン情報と<br/>サーバーのドメインが不一致"]

    style PHISHING fill:#e74c3c,color:#fff
    style BLOCK1 fill:#f39c12,color:#fff
    style BLOCK2 fill:#f39c12,color:#fff
    style BLOCK3 fill:#2ecc71,color:#fff
防御層仕組み
1. ブラウザアクセス中のドメイン情報を認証器に正確に伝達する
2. 認証器ドメインに紐づいた鍵のみを提示する(evil.com 用の鍵は存在しない)
3. サーバー署名データ内のドメイン情報を検証し、不一致なら拒否する

従来のチャレンジ・レスポンス認証では、中間者がチャレンジを中継すれば突破できました。FIDO2 ではドメインがプロトコルレベルで暗号的に紐づいているため、中継攻撃も構造的に無効化されます。

パスワード認証との比較

観点パスワード認証FIDO2(パスキー)
送信される情報パスワード(秘密そのもの)署名データ(秘密は送らない)
サーバー保存パスワードハッシュ公開鍵(漏洩しても無害)
フィッシング耐性なしあり(ドメイン紐づけ)
リプレイ攻撃可能不可能(チャレンジが毎回異なる)
中間者攻撃OTP でも防げない場合あり構造的に防御
ユーザー負担記憶・管理が必要生体認証/PIN のみ

日本での導入加速 — 2026 年の現状

金融業界の必須化

2025 年 10 月、日本証券業協会は不正アクセス防止のガイドラインを改正し、フィッシング耐性のある多要素認証の導入を求めました。特筆すべきは、ワンタイムパスワード(OTP)が非推奨とされた点です。OTP はフィッシングサイトによるリアルタイム中継攻撃に脆弱であり、FIDO2/パスキーが推奨認証方式として明確に位置づけられました。

証券会社導入状況
SMBC 日興証券2026 年 1 月に富士通のパスキー認証を導入済み
楽天証券2025 年 10 月にパスキー認証を導入済み
SBI 証券FIDO2 導入を発表

グローバルな普及状況

サービスパスキー導入状況
Google8 億以上のアカウントでパスキー利用
Amazon初年度に 1 億 7,500 万人がパスキー作成
Microsoft新規アカウントのデフォルトをパスキーに設定(2025 年 5 月)
AppleiCloud Keychain でデバイス間同期

日本では LINE ヤフー、メルカリ、NTT ドコモ、任天堂なども導入を進めており、FIDO Japan Working Group の会員組織は 64 に達しています。

パスキーの課題と注意点

パスキーは万能ではありません。現時点では以下の課題があります。

デバイス紛失・故障時のリカバリー

パスキーはデバイスに紐づいているため、デバイスを紛失・故障した場合、そのパスキーは利用できなくなります。パスワードのように「パスワードを忘れた場合」のような単純な復旧プロセスは存在しません。

対策: 複数デバイスにパスキーを登録しておく、またはリカバリー手段(SMS 認証等)を併用することが推奨されます。

エコシステム間の同期制限

パスキーの同期は同じエコシステム内に限られます。Apple なら iCloud Keychain、Google なら Google Password Manager を介して同期されますが、Apple デバイスで作成したパスキーを Android で直接使うといったクロスエコシステム同期はできません。

対策: 1Password や Bitwarden などのクロスプラットフォーム対応パスワードマネージャーの利用が有効です。

クラウド同期に伴う新たなリスク

パスキーをクラウド同期すると、デバイス紛失時の復旧は容易になります。一方で、クラウドアカウントが乗っ取られると同期されたパスキーも危険にさらされるという新たなリスクが生じます。

認証後の攻撃には無防備

FIDO2 は認証プロセスの安全性を保証しますが、認証後のセッション管理は対象外です。セッション Cookie の窃取、アクセストークンのリプレイ、悪意のある OAuth 同意など、認証後の攻撃には別の対策が必要です。

開発者向け — WebAuthn API の基本

Web アプリケーションにパスキーを実装する際の基本的な API 呼び出しです。

登録(Credential Creation)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const credential = await navigator.credentials.create({
  publicKey: {
    challenge: new Uint8Array(/* サーバーから受信 */),
    rp: { name: "Example Corp", id: "example.com" },
    user: {
      id: new Uint8Array(/* ユーザーID */),
      name: "user@example.com",
      displayName: "User"
    },
    pubKeyCredParams: [
      { alg: -7, type: "public-key" },   // ES256
      { alg: -257, type: "public-key" }  // RS256
    ],
    authenticatorSelection: {
      authenticatorAttachment: "platform",
      residentKey: "required",
      userVerification: "required"
    }
  }
});

認証(Assertion)

1
2
3
4
5
6
7
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: new Uint8Array(/* サーバーから受信 */),
    rpId: "example.com",
    userVerification: "required"
  }
});

residentKey: "required" を指定することで、Discoverable Credential(パスキー)として登録されます。認証時にユーザー名の入力が不要になり、認証器が自動的に該当する鍵を提示します。

まとめ

  • パスワード認証の根本的な問題は「秘密を送信する」設計にあり、FIDO2 は「秘密を送らない」ことで構造的に解決しています
  • FIDO2 = WebAuthn + CTAP2 の 2 層構造で、ブラウザ-サーバー間とブラウザ-認証器間の通信をそれぞれ標準化しています
  • 3 層のフィッシング防御(ブラウザのドメイン伝達 → 認証器のドメイン検証 → サーバーの署名検証)により、フィッシング攻撃を構造的に無効化します
  • 日本の金融業界では OTP が非推奨となり、FIDO2/パスキーへの移行が加速しています。楽天証券、SMBC 日興証券、SBI 証券が導入済みまたは導入予定です
  • Google で 8 億アカウント、Amazon で 1.75 億人がパスキーを利用するなど、グローバルでも急速に普及しています
  • デバイス紛失時のリカバリーやエコシステム間の同期制限など課題も残りますが、複数デバイス登録やクロスプラットフォームのパスワードマネージャーで対処可能です
  • 認証後の攻撃(セッション窃取等)には別途対策が必要で、パスキーだけで全てのセキュリティ問題が解決するわけではありません

参考