FIDO認証・パスキーとは?生体情報が送られない理由とWebAuthnの仕組み
パスワード、生体認証、公開鍵暗号から出発し、FIDO2・WebAuthn・CTAP、スマートフォンの認証器、IdPとWebサービスの関係、署名検証、フィッシング耐性を通信図と操作ラボで詳しく解説します。
最初に知っておきたい結論
指紋でログインしても、指紋をサーバーへ渡しているわけではない
パスキーは公開鍵暗号の鍵ペアを用いたログイン用の認証情報です。指紋・顔認証・端末のPINは、手元の認証器で秘密鍵を使ってよいか確認するために使用します。外部のサービスに送るのは、生体画像ではなく秘密鍵で作った電子署名と検証に必要な公開情報です。
端末内
生体照合・PIN確認・秘密鍵の操作
ネットワーク
challenge・署名・認証用データ
認証サーバー
公開鍵を使って署名と送信元の条件を検証
1. そもそも認証とは? パスワード・本人確認・権限の違い
認証(Authentication)は「利用者が誰かを確かめる」処理、認可(Authorization)は「その利用者に何を許可するか」を決める処理です。本人確認に成功しても、管理者専用の操作が許可されるわけではありません。
従来のパスワード方式では、利用者が秘密の文字列を入力し、サービス側が保存したパスワードの検証情報と照合します。パスワードは偽サイトへの入力、使い回し、漏えいなどの問題があります。パスキーは、サービスと人間の間で共通の秘密文字列を共有する必要をなくす仕組みです。
知識要素
所持要素
生体要素
2. 公開鍵暗号と電子署名をゼロから理解する
パスキーの中心には、公開鍵(public key)と秘密鍵(private key)の組があります。名前は似ていますが役割が異なります。秘密鍵は他人に渡さない鍵、公開鍵は検証する相手に渡してよい鍵です。
「公開鍵暗号」という言葉から暗号化・復号を連想しがちですが、パスキーのログインで主に使うのは電子署名です。秘密鍵でデータに署名し、公開鍵でその署名が有効か確かめます。署名は指紋画像の暗号化や送信ではありません。
手元の認証器
秘密鍵
外へ配らない。サーバーからのchallenge等に対する署名を作る。
IdP / Webサービス
公開鍵
登録時に受け取る。ログイン時の署名が正しいかを検証する。
チャレンジ(challenge)は、サーバーがその都度作る予測困難な値です。以前のログインで得た署名を使い回すリプレイ攻撃を防ぐために利用します。「今回指定したchallengeを含むデータへの署名であるか」が重要です。
3. ブラウザ・スマートフォン・IdP・Webサービスは何者なのか
登場人物を区別すると、複雑なログインが理解しやすくなります。スマートフォンがブラウザと同じ端末でも、別端末でも、ブラウザ(クライアント)と認証器は役割が異なります。
① ブラウザ(WebAuthnクライアント)
② スマートフォンの認証器
③ IdP(Identity Provider)
④ WebサーバーB(サービス)
ここにはRP(Relying Party)という用語が2つの文脈で登場し得ます。WebAuthnでのRPは公開鍵を登録し署名を検証する主体(この構成ではIdP)、フェデレーション認証でのRPはIdPによる認証結果を利用するサービスBを指します。文脈を曖昧にせずに説明することが重要です。
IdPとサービスBの連携には、たとえばOpenID Connect(OIDC)を使えます。OIDCはOAuth 2.0を土台とする本人認証の仕組みです。IdPでのFIDO認証と、サービスBへのログイン連携は別のプロトコル層の処理です。IdPが生成するIDトークンはログインの証明であり、生体画像ではありません。
4. FIDO・FIDO2・WebAuthn・CTAP・パスキーの関係
| 用語 | 何を指すか | 主な担当範囲 |
|---|---|---|
| FIDO Alliance | 業界団体 | 認証関連仕様の策定・普及 |
| FIDO2 | WebAuthnとCTAPなどの技術体系 | 公開鍵ベースのユーザー認証 |
| WebAuthn | W3CのブラウザAPI・仕様 | Webアプリとブラウザ間の登録・認証 |
| CTAP | 認証器とクライアントのためのプロトコル | 外付けやクロスデバイス認証器とのやり取り |
| パスキー | FIDO認証情報 | Webサイト別の公開鍵・秘密鍵によるログイン |
内蔵認証器はOSの内部APIでブラウザと連携することもあります。すべての構成でCTAPが物理的な通信として観測できるわけではありません。また、従来のFIDO UAF・U2Fの仕様とFIDO2の区別もあります。
レイヤを分けて理解する
Webアプリ ↔ ブラウザ:WebAuthn API
ブラウザ ↔ 認証器:OSの認証機能やCTAP
ブラウザ ↔ IdP:HTTPSでWebAuthn用データを受け渡し
IdP ↔ サービスB:OIDCなどで認証結果を利用
5. 初めての登録:指紋ではなく「公開鍵」を登録する
パスキーを使うには、認証器側で鍵ペアを用意し、検証する側へ公開鍵を登録します。登録時にIdPへ指紋画像を渡すわけではありません。登録後、公開鍵に対応する秘密鍵を使ってログインのたびに署名します。
STEP 01
IdPから登録依頼
challenge・RP ID・利用者情報などを渡す
STEP 02
認証器で鍵生成
端末内で本人確認し、公開鍵と秘密鍵を用意
STEP 03
IdPへ公開鍵登録
公開鍵・credential ID等を保持して後のログインを検証
// 概念的な登録レスポンス(実際はバイナリ・CBOR等を含む)
{
id: "credential-abc123",
type: "public-key",
response: {
clientDataJSON: "...challenge と origin...",
attestationObject: "...認証器データと公開鍵..."
}
}
// × 指紋画像を送るフィールドはない登録時にはattestation(アテステーション)という仕組みが関係することがあります。これは認証器の特性を証明するための情報であり、顔や指紋の画像を提出することではありません。実際にどのアテステーション方式を採用・検証するかはサービスの方針によります。
6. 操作ラボ:4者のノード図で登録・ログイン・偽サイトを追跡
ラボでは、ブラウザ・スマホ認証器・IdP・WebサーバーBの4者を同じ図に表示します。「次の通信」で進めると、現在どのノードが送信・処理しているか、何がデータとして渡されるかを確認できます。
INTERACTIVE AUTHENTICATION LAB
何がどこへ届く? 4者の認証フロー
ここに現れるのは概念的な通信経路です。生体画像・指紋データが外部ノードに移動する場面はありません。
ログイン開始
利用者がサービスBへのログインを開始。ブラウザはサービスにアクセスします。
受信・処理する場所:WebサーバーB
注目したいのは、**ローカル生体照合**のステップと、**署名付き応答がIdPへ向かう**ステップの違いです。生体照合が成功しても、IdP側はその生体情報自体を受信しません。IdPが確認するのは、登録済み公開鍵に対応する署名と関連するセキュリティ条件です。
7. 具体的な通信データ:WebAuthnのどこに何が入る?
ログイン時にブラウザの navigator.credentials.get() を使うと、認証器が署名した結果を表すPublicKeyCredentialが返ります。代表的な要素を見ます。
// 説明用の擬似コード:本番実装には完全な検証が必要
const credential = await navigator.credentials.get({
publicKey: {
challenge: serverGeneratedRandomBytes,
rpId: "login.example.test",
userVerification: "required"
}
});
// 主要な返却要素
credential.response.authenticatorData; // RP IDハッシュ、UP/UVフラグ等
credential.response.clientDataJSON; // challenge、origin、type等
credential.response.signature; // 秘密鍵を使った署名
credential.response.userHandle; // ある場合は利用者識別子
// 生体画像・指紋テンプレートを返すフィールドはないclientDataJSON
authenticatorData
signature
authenticatorData || SHA-256(clientDataJSON) に対する署名です。IdPは公開鍵で検証します。credential ID
WebAuthnにおけるUV(User Verified)フラグは、認証器が利用者検証を行ったことを表します。しかし、「指紋認証だったか」「顔認証だったか」「どんな生体データだったか」をサーバーへ知らせるものではありません。PINなどによる検証でもUVが成立し得ます。
8. なぜフィッシングに強いのか:RP IDとorigin
パスワードは、偽サイトで入力してしまうと、その文字列を攻撃者に渡してしまいます。パスキーは登録先サービスのRP ID(WebAuthnで指定するドメイン)と結び付きます。ブラウザはRP IDの使用条件を検査し、要求元のoriginも認証データに含まれるため、サービス側で検証できます。
正規サイト
https://login.example.test
RP IDとの関係が正しく、IdPは署名とorigin等を検証します。
見た目の似た偽サイト
https://login-example.test
ドメインが別物です。正規サイト用のパスキーをそのまま偽サイトで利用することはできません。
ただし、パスキーさえ使えばすべての乗っ取りが防げるわけではありません。悪意あるブラウザ拡張、端末乗っ取り、セッションCookieの窃取、弱いアカウント復旧フローなどは別途対策が必要です。IdPとWebサービス間のセッション管理やIDトークンの検証も重要です。
9. 同期パスキー・端末固定型・クロスデバイス認証
同期パスキー(synced passkey)
端末固定型パスキー(device-bound passkey)
別の端末にあるパスキーを使う
スマートフォンに登録した生体認証機能を使う場合、実際の画面や通信経路はOS・ブラウザ・IdPによって異なります。WebAuthnの重要な共通原則は、秘密鍵の操作とローカル利用者検証を認証器が担当し、サーバーが署名等を検証することです。
10. どこが生体情報を受信する? 構成要素ごとに整理
| 構成要素 | 生体情報 | 実際に扱うもの |
|---|---|---|
| スマホの認証器 | ローカルで利用 | 顔・指紋等のローカル照合、秘密鍵を使った署名 |
| ブラウザ | 受け取らない | チャレンジや署名付きWebAuthn応答を中継 |
| IdP | 受け取らない | 登録公開鍵、署名、challenge、origin等の検証 |
| WebサーバーB | 受け取らない | IdPの認証結果やログインセッション |
ブラウザやサービスBだけでなく、IdPも生体情報そのものを受け取らないのがポイントです。代わりに公開鍵暗号を使って「登録済みの鍵を利用できる認証器が今回の要求に応答した」という事実を検証します。
11. よくある疑問
指紋を登録したらサーバーにも指紋が保存される?
FIDO2/WebAuthnの一般的なパスキー認証では、サーバーに保存するのは公開鍵等の認証資格情報であり、生体情報そのものではありません。
PINで解除したらパスキーではなくなる?
いいえ。PINは秘密鍵を使うためのローカル利用者検証の方法の一つです。パスキーを用いる公開鍵署名による認証は変わりません。
生体情報を送らないのに本人確認できる理由は?
認証器がローカルで検証を行った後に、秘密鍵でchallenge等に署名するためです。サーバーは公開鍵で署名を検証します。
WebサービスとIdPは同一サーバーでもよい?
はい。パスキーをサイト自身が直接検証する構成もあります。IdPへ委任するのはフェデレーション認証を採用する場合の一つの設計です。
ブラウザには署名が届くのに「生体情報は届かない」でよい?
その通りです。署名は秘密鍵を用いて生成した暗号学的データであり、生体情報とは別です。
一次資料・公式仕様
WebAuthnの正確な検証項目やFIDO2の構造は、次の公式資料でも確認できます。