本文へスキップ
株式会社オープンナレッジ
株式会社オープンナレッジ Open Knowledge Inc.
W3C WebAuthn / FIDO2 Passkey 読了目安:約3分 対象:経営者・総務ご担当者・ご家族

パスワード暗記が不要になる「パスキー(FIDO2)」安心ガイド:フィッシング詐欺を仕組みで防ぐ玄関の生体鍵

監修:加藤 明生(登録情報処理安全確保支援士(第007617号))

1. 基本と全体像

この記事の要点と4つの章のご案内

身近なたとえで見る仕組み:「合言葉の紙メモ」と「ドアと対になるスマートキー」に関するイメージ写真
身近なたとえで見る仕組み:「合言葉の紙メモ」と「ドアと対になるスマートキー」
図解で見る仕組み:パスワードとパスキーのちがいに関するイメージ写真
図解で見る仕組み:パスワードとパスキーのちがい
パスワード暗記が不要になる「パスキー(FIDO2)」安心ガイド:フィッシング詐欺を仕組みで防ぐ玄関の生体鍵 の各章におけるテーマと要点一覧表
章構成 主なテーマ 要点と確認ポイント
1. 基本と全体像 身近なたとえで見る仕組み:「合言葉の紙メモ」と「ドアと対になるスマートキー」 指紋や顔のデータはお手元のスマホやPCの安全チップ(Secure Enclave / TPM)内だけで照合され、外部サーバーへは一切送信されません。
2. 現場での進め方と対策 図解で見る仕組み:パスワードとパスキーのちがい AppleやGoogleアカウント等で安全に同期されるため機種変更時も引き継げます。紛失時も生体認証が守るため悪用されず、別端末からログイン可能です。
3. 関連する制度とルール 実践のポイント:パスキーが守る3つの安心 はい。Windows HelloやMacのTouch IDを使って、業務パソコン自体にパスキーを登録できます。
4. 詳しい技術仕様としくみ パスキーを使うと、指紋や顔のデータが運営会社に送られませんか? 「パスキー(FIDO2)」は、文字列を暗記する代わりにスマホやPCの指紋・顔認証でログインできる新しい生体鍵です。本物のサイトと端末が1対1で結びつくため、偽サイトを開いても仕組み上「鍵が原則として開かない」安心が手に入ります。
第1章〜第4章では、実務チェックリスト・公的制度基準・詳しい技術仕様を確認できます。

この記事の要点

「パスキー(FIDO2)」は、文字列を暗記する代わりにスマホやPCの指紋・顔認証でログインできる新しい生体鍵です。本物のサイトと端末が1対1で結びつくため、偽サイトを開いても仕組み上「鍵が原則として開かない」安心が手に入ります。

01. 身近なたとえで見る仕組み:「合言葉の紙メモ」と「ドアと対になるスマートキー」

従来の方式は「合言葉の紙メモ(パスワード)」でした。泥棒が偽窓口を作って尋ねれば、人間はうっかり教えてしまいます。一方パスキーは「本人とドアが対になるスマートキー(公開鍵暗号)」です。偽ドアの前ではドメインが一致せず反応しないため、鍵を盗まれません。

フィッシング対策協議会

年間171万件超

フィッシング報告件数は年間171万件超。目視だけで偽サイトを見抜くのは困難です。

IPA / Verizon統計

原因の80%以上

不正ログイン原因の80%以上がパスワード使い回し・窃取に起因しています。

公開鍵暗号の防御効果

フィッシング突破率 0%

偽サイトではドメイン不一致で鍵が作動しないため、フィッシング突破率0%を実現します。

02. 図解で見る仕組み:パスワードとパスキーのちがい

従来:合言葉の紙メモ(偽サイトに手入力すると中間者攻撃で盗まれる) 利用者(手入力) パスワード+SMSコード送信 偽サイト(AiTM中継プロキシ) 合言葉を中継しセッション窃取 不正ログイン被害 口座・業務クラウドへ侵入 パスキー(FIDO2):Origin束縛型スマートキー(URLが一致する本物のドアだけ開く) 端末内の秘密鍵(TPM/Enclave) 指紋・顔データは外に出ない 本物サイト(公開鍵で検証) rpIdHash一致時のみ1秒開錠 偽サイトは自動遮断 ドメイン不一致で突破率0%
比較項目 従来のやり方・よくある課題 パスキー(FIDO2)による解決策
ログイン操作 長い文字列を暗記・手入力しSMSコードも打ち直す 指紋・顔認証に1秒触れるだけ(暗記・手入力ゼロ)
偽サイト対策 偽画面にうっかり入力するとその場で突破される ブラウザがURLを自動照合し偽サイトでは鍵が開かない
定期変更負担 定期変更を強いられ付箋メモや使い回しが発生 定期変更不要。一度設定すればずっと安全・快適

03. 実践のポイント:パスキーが守る3つの安心

1. なぜSMS確認コードだけでは防げなくなったのか

近年のフィッシング詐欺(AiTM:Adversary-in-the-Middle攻撃)は、偽画面に入力されたパスワードとSMSコードを0.1秒で本物サイトへ中継します。人間の目視だけに頼らず、文字を入力しない認証への移行が重要です。

2. 指紋や顔のデータは端末の外へ一切出ない

パスキーではサービス側に「鍵穴(公開鍵)」だけを預け、「鍵(秘密鍵)」は端末内の安全チップに保管されます。生体情報は端末内で鍵を動かすためだけに使われ外部には送られません。

3. 中小企業は「メール・会計・通販」の3つから開始

Google、Microsoft 365、freee会計、Amazon等は無料でパスキーに対応済みです。重要窓口から有効化するだけで、経産省「SCS評価制度(★3)」の認証強化要件にも直結します。

今日からできる3項目チェックリスト

技術仕様・実装解説(W3C WEBAUTHN LEVEL 3 & FIDO2 CTAP2 CRYPTOGRAPHY) 4. 詳しい技術仕様としくみ
技術アーキテクチャと実装仕様

W3C WebAuthn Level 3 / FIDO2 における authenticatorData バイト構造と COSE ES256 (P-256) / Ed25519 署名検証

本稿では、フィッシング詐欺やクレデンシャル・スタッフィング攻撃を暗号学的に無効化する『パスキー(Passkey / FIDO2 WebAuthn)』のプロトコル内部構造をバイト単位で詳細解説し、(1) ブラウザ層が clientDataJSON.origin をハードウェア署名対象へ束縛するフィッシング耐性の数理証明、(2) 37バイト以上の authenticatorData(rpIdHash + flags + signCount + COSE公開鍵)のバイナリレイアウト、および (3) Rust によるゼロアロケーション認証データ検証実装を提示する。

Protocol Standard
W3C WebAuthn L3 / FIDO2 CTAP2.1
Elliptic Curves
COSE ES256 (-7) / EdDSA (-8)
Origin Binding
SHA-256(rpId) + clientDataJSON
Replay & Clone Guard
32-bit Big-Endian signCount
1. 設計仕様・数理モデル(Formal Architecture, Protocol Internals & Mathematical Formulation)

1. 【なぜ従来のSMS二要素認証(OTP)はリアルタイム・リバースプロキシ型フィッシングに無力なのか】 Evilginx 等の Man-in-the-Middle(MitM)フィッシングキットは、被害者が偽サイト(例:login-bank-secure.example)に入力したID・パスワード・6桁のワンタイムパスコード(TOTP/SMS)をミリ秒単位で正規サイトへ中継し、発行されたセッショントークン(Cookie)を奪取する。人間が文字列を読み取って手入力する方式である限り、どれほど桁数を増やしてもオリジン(ドメイン名)の真正性を暗号学的に束縛できないためである。

2. 【WebAuthn における Origin 束縛の暗号学的証明】 WebAuthn(navigator.credentials.get)では、ブラウザ(User Agent)が TLS チャネルの接続先オリジンを検証した上で clientDataJSON({"type":"webauthn.get","challenge":"...","origin":"https://ok.st"})を生成し、またスマートフォンの Secure Enclave / TPM 内の認証器(Authenticator)は要求元の Relying Party ID の SHA-256 ハッシュ rpIdHash = SHA256(rpId)(32バイト)に紐づく秘密鍵 sk_RP のみを検索する。仮に攻撃者がフィッシングサイト上で WebAuthn API を呼び出しても、ブラウザが origin に攻撃者のドメインを刻印し、認証器は正規サイトの秘密鍵を一切解放しないため、フィッシングはプロトコル層で 100% 失敗する。

3. 【authenticatorData のバイナリ構造(37+ bytes)と署名対象データの結合】 認証器が生成する authenticatorData は、先頭 32バイトが rpIdHash、オフセット 32(1バイト)が flags ビットフィールド(Bit 0 UP: User Present、Bit 2 UV: User Verified[生体認証またはPIN完了]、Bit 3 BE: Backup Eligible、Bit 4 BS: Backup State、Bit 6 AT: Attested Credential Data 付属)、オフセット 33〜36(4バイト Big-Endian u32)が署名カウンタ signCount である。最終的な ECDSA P-256(COSE alg = -7)または Ed25519(COSE alg = -8)の署名は、authData || SHA256(clientDataJSON) の連結バイト列に対して計算される。

2. パラメータ・構成仕様(W3C WebAuthn authenticatorData Binary Layout (RFC 9052 COSE & CTAP2))
Byte OffsetField NameLength (Bytes)Bitwise / Cryptographic Verification Rule
0x00 .. 0x1FrpIdHash32 BytesMust equal SHA-256(relying_party_domain_ascii) in constant time
0x20flags1 Byte (u8)Bit 0 (UP=0x01) & Bit 2 (UV=0x04) must be 1 for passwordless MFA login
0x21 .. 0x24signCount4 Bytes (u32 BE)If > 0, must be strictly greater than stored_sign_count (clone detection)
0x25 .. EndattestedCredentialDataVariable (Registration)16B AAGUID + 2B credIdLen + credId + CBOR COSE_Key (kty, alg, crv, x, y)
3. 実装コード・設定仕様(Executable Specification Code (crates/ok-webauthn-core/src/auth_data_parser.rs)) Rust Edition 2024 (#![forbid(unsafe_code)])
#![forbid(unsafe_code)]

pub const FLAG_USER_PRESENT: u8 = 1 << 0; — 0x01 (UP)
pub const FLAG_USER_VERIFIED: u8 = 1 << 2; — 0x04 (UV)
pub const FLAG_BACKUP_ELIGIBLE: u8 = 1 << 3; — 0x08 (BE - Synced Passkey capability)
pub const FLAG_BACKUP_STATE: u8 = 1 << 4; — 0x10 (BS - Currently backed up)
pub const FLAG_ATTESTED_CRED: u8 = 1 << 6; — 0x40 (AT)

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParsedAuthData<'a> {
    pub rp_id_hash: &'a [u8; 32],
    pub flags: u8,
    pub sign_count: u32,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WebAuthnVerifyError {
    BufferTooShort,
    RpIdHashMismatch,
    UserPresenceRequired,
    UserVerificationRequired,
    ClonedAuthenticatorSuspected { stored: u32, received: u32 },
}

/// Parses and validates the 37-byte header of a WebAuthn `authenticatorData` payload
/// in constant time without heap allocations.
pub fn verify_authenticator_data<'a>(
    raw: &'a [u8],
    expected_rp_id_hash: &[u8; 32],
    stored_sign_count: u32,
    require_user_verification: bool,
) -> Result<ParsedAuthData<'a>, WebAuthnVerifyError> {
    if raw.len() < 37 {
        return Err(WebAuthnVerifyError::BufferTooShort);
    }
    let rp_id_hash: &[u8; 32] = raw[0..32].try_into().unwrap();

    // Constant-time 32-byte comparison to prevent timing side-channels
    let mut diff: u8 = 0;
    for i in 0..32 {
        diff |= rp_id_hash[i] ^ expected_rp_id_hash[i];
    }
    if diff != 0 {
        return Err(WebAuthnVerifyError::RpIdHashMismatch);
    }

    let flags = raw[32];
    if (flags & FLAG_USER_PRESENT) == 0 {
        return Err(WebAuthnVerifyError::UserPresenceRequired);
    }
    if require_user_verification && (flags & FLAG_USER_VERIFIED) == 0 {
        return Err(WebAuthnVerifyError::UserVerificationRequired);
    }

    let sign_count = u32::from_be_bytes([raw[33], raw[34], raw[35], raw[36]]);
    if (sign_count > 0 || stored_sign_count > 0) && sign_count <= stored_sign_count {
        return Err(WebAuthnVerifyError::ClonedAuthenticatorSuspected {
            stored: stored_sign_count,
            received: sign_count,
        });
    }

    Ok(ParsedAuthData {
        rp_id_hash,
        flags,
        sign_count,
    })
}
4. 詳しい技術仕様としくみ(システム設計・数理モデル・実装例)

FIDO2 / WebAuthn Level 3 と CTAP2 公開鍵暗号によるフィッシング無効化プロトコル実装

プロトコル仕様・数理モデル・Rust 2024 実装コードの詳細は、専門技術モノグラフにて公開しています。

技術モノグラフを読む →
ご質問・公的制度の活用に関するお問い合わせ窓口

掲載資料に関するご質問・公的制度活用のご案内

本ページの図解や解説内容に関するご質問、経済産業省「SCS評価制度」やIPA「SECURITY ACTION・サイバーセキュリティお助け隊サービス」等の公的制度の確認方法について、落ち着いた参考窓口としてご案内しております。売り込みや営業連絡は一切行いませんので、社内勉強会やご家庭での確認資料としてご自由にご活用ください。

図解・ビジュアルの拡大表示

図表内のテキストもそのまま選択・検索可能です(ベクターSVG描画) 枠外クリックまたは ESC キーで閉じます