目次
第1章 パスキー導入が求められる背景
 ── 既存の認証方法とパスキーの背景を知ろう
1.1 パスワード
- パスワード認証のしくみとその問題点
- ユーザーが弱いパスワードを作ってしまう
 - ユーザーが同じパスワードを使いまわしてしまう
 - ユーザーがフィッシングサイトにパスワードを入力してしまう
 
 - パスワードマネージャー
- パスワードマネージャーを使うことの利点
 - パスワードマネージャーの問題点
 
 
1.2 二要素認証
- 二要素認証とは何か
- 認証の三要素と二要素認証
 - 二段階認証
 
 - SMS OTP
- 送信コストの負担
 - SIM自体の安全性
 - フィッシング耐性
 
 - メールOTP
 - TOTP
 - プッシュ通知
 - セキュリティキー
- ユーザー存在テスト
 - フィッシング耐性
 - 物理的制約
 - FIDO2対応セキュリティキー
 - [Column]NIST SP 800-63
 
 
1.3 パスワードレス
- マジックリンク
 - SMS認証
 
1.4 ID連携
1.5 まとめ
- [Column]公開鍵暗号をざっくりと理解する
 
第2章 パスキーを理解する
 ── パスキーの特徴や利点を理解しよう
2.1 WebAuthnとFIDO2の登場
- デバイス認証
 - ローカルユーザー検証
 - デバイス認証の欠点
 
2.2 パスキーの登場
- ディスカバラブル クレデンシャル
 - パスキープロバイダを使ったパスキーの同期
- パスキーはどのようにして同期されるのか
 - サードパーティのパスキープロバイダを利用する
 
 - 同期パスキーとデバイス固定パスキー
 - 本書でのパスキーの定義
- [Column]ディスカバラブルでないクレデンシャル
 
 
2.3 パスキーの何が優れているのか
- リモート攻撃が難しい
 - 脆弱なクレデンシャルを作ることができない
 - 公開鍵が漏れてもアカウントが盗まれる危険性は低い
 - フィッシング攻撃に強い
 - ログイン体験がシンプル
 
2.4 パスキーのよくある誤解を解く
- デバイスを失くしたらパスキーが使えなくなるのでは?
 - パスキーを使うと生体情報が収集されるのでは?
 - パスキーはトラッキングに使うことができるのでは?
 - パスワードマネージャーの事業者は秘密鍵にアクセスできるのでは?
 - Webサイト側で保存する公開鍵は暗号化しておく必要があるのでは?
 - 同期パスキーよりも同期しないパスキーのほうが安全なのでは?
 - パスキーは二要素認証で利用するもの?
- [Column]パスキーは多要素認証ではない場合もあるのでは?
 
 
2.5 パスキーも銀の弾丸ではない
- セッションCookieが盗まれたら?
 - PINを盗み見たうえでデバイスを盗まれたら?
 - パスワードマネージャーのログインアカウントが乗っ取られたら?
 - パスキーにアクセスできなくなったら?
 
2.6 まとめ
- [Column]アカウントのライフサイクルとパスキーの関係性
 
第3章 パスキーのユーザー体験
 ── パスキーの体験をイメージしよう
3.1 パスキーによるアカウントの新規登録
3.2 既存アカウントへのパスキーの登録
- ログイン直後にパスキー登録を促すプロモーションを表示する
- パスキー登録訴求の注意点
 - ケーススタディ
 
 - パスキーの管理画面にパスキー登録ボタンを表示する
 - アカウントリカバリ時に,新しいパスワードの代わりにパスキー登録ボタンを表示する
 - パスキープロバイダからの誘導で登録する
 - パスワードログイン時に自動的にパスキーを登録する
 
3.3 パスキーによる認証
- ワンボタンログインによるパスキー認証
- ケーススタディ
 
 - フォームオートフィルによるパスキー認証
- ケーススタディ
 
 
3.4 パスキーによる再認証
- パスキーによる再認証フロー
- ケーススタディ
 
 
3.5 クロスデバイス認証
3.6 パスキーの管理画面
- パスキーの一覧
- パスキーの名前とアイコン
 - 登録日時・最終使用日時・使用したOS
 - 同期パスキーとデバイス固定パスキーのラベル
 - 名前の編集ボタン
 - 削除ボタン
 
 - 新規登録ボタン
 - テストボタン
 - ケーススタディ
 
3.7 まとめ
- [Column]パスキーの他人との共有
 - [Column]クロスデバイス認証のしくみ
 
第4章 サポート環境
 ── ユーザーの環境ごとに利用できる機能を確認しよう
4.1 ユーザーエージェント
- ブラウザ
- Chromium
 - Gecko
 - WebKit
 
 - ネイティブアプリ
 - WebView
 - アプリ内ブラウザ
 
4.2 パスキープロバイダ
- パスキーの保存先
- スマートフォン
 - デスクトップ
 
 - 主なパスキープロバイダ
- iCloudキーチェーン
 - Googleパスワードマネージャー
 - Windows Hello
 - サードパーティパスキープロバイダ
 
 
4.3 OSごとの挙動
- Windows
- Edge
 - Chrome
 - Firefox
 
 - macOS
- Safari
 - Chrome
 - Firefox
 
 - iOS,iPadOS
 - Android
- Chrome
 - Edge
 - Firefox
 
 - ChromeOS
 - Linux
 
4.4 まとめ
第5章 パスキーのUXを実装する
 ── UXの実現に必要なメソッドやパラメータを知ろう
5.1 共通処理
- パスキー作成リクエストのサーバからの取得と作成レスポンスのサーバへの返却
 - パスキー認証リクエストのサーバからの取得と認証レスポンスのサーバへの返却
 
5.2 パスキー登録UXの実装
- パスキーが登録できる環境かを検知する
 - パスキー作成リクエスト
- ❶challenge ── CSRFやリプレイ攻撃からの防御
 - ❷rp ── RPに関する情報
 - ❸user ── ユーザーに関する情報
 - ❹excludeCredentials ── 同一ユーザーで登録済みのクレデンシャルIDのリスト
 - ❺authenticatorAttachment ── パスキーの保存場所
 - ❻requireResidentKey ── ディスカバラブル クレデンシャル
 - ❼userVerification ── ローカルユーザー検証
 - ❽hints ── RPが要求する認証ダイアログのヒント
 
 - サーバ処理
 
5.3 パスワードログイン時に自動でパスキー登録するUXの実装
- ❶getClientCapabilities() ── 各種パスキーの機能検知
 - ❷conditionalCreate ── 自動パスキー作成の検知
 - ❸mediation ── 自動的にパスキーを作成
 - 自動パスキー登録が発動しないケース
 - サーバ処理
 
5.4 ワンボタンログインUXの実装
- パスキーで認証できる環境かを検知する
 - ワンボタンログイン認証リクエスト
- ❶challenge ── CSRFやリプレイ攻撃からの防御
 - ❷rpId ── RPのIDを指定
 - ❸userVerification ── ローカルユーザー検証
 
 - サーバ処理
 
5.5 フォームオートフィルログインUXの実装
- フォームオートフィルログインが利用できる環境かを検知する
 - フォームオートフィルログイン認証リクエスト
- ❶mediation ── パスキー登録済みのユーザーにだけ選択肢を見せたい
 - ❷autocomplete="webauthn" ── パスキーでもパスワードのオートフィルと同じ挙動にする
 
 - サーバ処理
 
5.6 再認証UXの実装
- ワンボタンログイン方式の再認証リクエスト
- ❶allowCredentials ── 再認証したいアカウントに紐付くパスキーを指定して認証要求
 
 - フォームオートフィルログイン方式の再認証リクエスト
- ❶autocomplete="webauthn" ── パスキーでもパスワードマネージャーのオートフィルと同じ挙動にする
 
 - サーバ処理
 
5.7 クロスデバイスUXの実装
- クロスデバイスのパスキー作成リクエスト
- ❶authenticatorAttachment ── パスキーの保存場所を指定
 - ❷hints ── RPが要求する認証ダイアログのヒント
 
 - サーバ処理
 - クロスデバイス認証後にパスキー登録を訴求する
 
5.8 パスキー作成・認証の中断操作の実装
- ❶abortSignal ── パスキー中断の準備
 - ❷onabort ── 中断時に実行される処理の登録
 - ❸signal ── 中断を許可してパスキーを作成
 - ❹'AbortError' ── 中断によるパスキー認証(作成)失敗の検知
 - ❺abort() ── 特定の条件による中断の実行
 
5.9 管理画面UXの実装
- パスキーの一覧
- パスキーの名前とアイコン
 - 登録日時・最終使用日時・使用したOS
 - 同期パスキーのラベル
 - 名前の編集ボタン
 - 削除ボタン
 
 - 新規登録ボタン
 - テストボタン
 - パスキー削除とユーザー名・表示名の変更の注意点
 
5.10 まとめ
- [Column]PINを使わず,生体認証だけでパスキーを利用できるようにすることはできますか?
 
第6章 WebAuthn APIリファレンス
 ── クライアントとサーバの実装の詳細を確認しよう
6.1 実装の概要
- クライアント
 - Relying Party
- RP ID
 - eTLD
 - RP IDに設定できるドメイン
 
 - 認証器
 
6.2 パスキーに関する各種機能が利用可能かを確認する
- プラットフォーム認証器の利用可否
 - フォームオートフィルログインの利用可否
 - 利用可能な機能をまとめて確認する
 
6.3 パスキーを作ってみる
- パスキーを作成する
- navigator.credentials.create()
 
 - パスキー作成リクエスト ── 呼び出しパラメータの概要
- ❶challenge ── CSRFやリプレイ対策
 - ❷rp.name ── 登録,認証を行うRPの名前
 - ❸rp.id ── 登録,認証を行うRPの識別子
 - ❹user.id ── ユーザー識別子
 - ❺user.name ── ログイン時にユーザーに表示されるユーザー名
 - ❻user.displayName ── ログイン時にユーザーに表示される表示名
 - ❼pubKeyCredParams ── PublicKeyCredentialのタイプと署名アルゴリズム
 - ❽excludeCredentials ── 同じ認証器にパスキーを複数回重複して登録させないためのパラメータ
 - ❾authenticatorSelection.authenticatorAttachment ── 認証器タイプの制限
 - ❿authenticatorSelection.requireResidentKey ── 認証器へのユーザー情報の記録
 - ⓫authenticatorSelection.userVerification ── 認証器によるローカルユーザー検証の制御
 - ⓬timeout ── API実行の有効時間
 - ⓭hints ── RPが要求する認証方式のヒント
 
 - パスキー作成レスポンス ── 返却パラメータの概要
- ❶id ── エンコード済みのクレデンシャルID
 - ❷rawId ── クレデンシャルID
 - ❸response.clientDataJSON ── 登録リクエストのコンテキストを示すデータ
 - ❹response.attestationObject ── 生成された公開鍵本体を含むデータ
 - ❺authenticatorAttachment ── 認証器の接続形態を示すデータ
 - ❻type ── 公開鍵クレデンシャルのタイプ
 - ❼clientDataJSON.type ── レスポンスのタイプ
 - ❽clientDataJSON.origin ── オリジンの文字列
 - ❾clientDataJSON.challenge ── チャレンジの文字列
 
 - サーバ処理
- 事前準備
 - パスキー作成リクエストの生成
 - パスキー作成レスポンスの検証と保存
 - ❶attestationObjectの検証
 - ❷challengeの検証
 - ❸originの検証
 - ❹rp.idの検証
 - ❺ユーザー存在テスト結果の検証
 - ❻ローカルユーザー検証結果の検証
 - ❼データベースへの公開鍵の保存
 - ❽challengeの破棄
 
 
6.4 パスキーを使って認証してみる
- パスキーを使って認証する
- navigator.credentials.get()
 
 - パスキー認証リクエスト ── 呼び出しパラメータの概要
- ❶challenge ── CSRFやリプレイ対策用に必須
 - ❷allowCredentials ── 登録済み公開鍵クレデンシャル
 - ❸timeout ── API実行の有効時間
 - ❹userVerification ── 認証器によるローカルユーザー検証の制御
 
 - パスキー認証レスポンス ── 返却パラメータの概要
- ❶id ── エンコード済みのクレデンシャルID
 - ❷rawId ── クレデンシャルID
 - ❸response.authenticatorData ── 認証器の情報
 - ❹response.clientDataJSON ── 認証リクエストのコンテキストを示すデータ
 - ❺response.signature ── レスポンスに対する署名
 - ❻response.userHandle ── ユーザー識別子
 - ❼authenticatorAttachment ── 認証器の接続形態を示すデータ
 - ❽type ── PublicKeyCredentialのタイプ
 - ❾clientDataJSON.type ── レスポンスのタイプ
 
 - サーバ処理
 - 事前準備
 - パスキー認証リクエストの生成
 - パスキー認証レスポンスの検証
- ❶データベースから公開鍵データの検索
 - ❷データベースから公開鍵に紐付くアカウントの検索
 - ❸署名の検証
 - ❹challengeの検証
 - ❺originの検証
 - ❻rp.idの検証
 - ❼ローカルユーザー検証結果の検証
 - ❽データベースの公開鍵データの更新
 - ❾認証完了
 - ❿challengeの破棄
 
 
6.5 パラメータの深掘り
- authenticatorSelection
 - authenticatorSelection.authenticatorAttachment
- プラットフォーム認証器での登録を強制する
 - 外部の認証器(ローミング認証器)も選択肢に加える
 
 - authenticatorSelection.userVerification
- 'required' ── ローカルユーザー検証を必須にする
 - 'preferred' ── ローカルユーザー検証が利用可能な場合は実施する
 - 'discouraged' ── ローカルユーザー検証はなるべく実施しない
 
 - excludeCredentials
 - allowCredentials
 
6.6 まとめ
- [Column]パスキーの同期を禁止する方法はある?
 
第7章 スマホアプリ向けの実装
 ── AndroidとiOSにおける実装を確認しよう
7.1 iOS/iPadOS
- ASWebAuthenticationSessionを利用して,Webサイト上でパスキーでログインし,その結果を受け取る
 - ASAuthorizationPlatformPublicKeyCredentialProviderを利用して,ネイティブで実装する
- Associated Domainsとは
 - AppID,Provisioning Profileの作成
 - AASA(apple-app-site-association)ファイルの配置
 - Xcodeでの編集
 - 一度動かしてみる
 - 動かない場合は
 - パスキー作成
 - パスキーによる認証
 - API実行結果の取得
 - サーバとの通信処理
 
 
7.2 Android
- Custom Tabsを利用して,Webサイト上でパスキーを使用し,その結果を受け取る
 - Credential Managerを利用して,ネイティブで実装する
- Digital Asset Linksとは
 - assetlinks.jsonファイルをWebサイトに配置する
 - アプリからもassetlinks.jsonファイルを参照する
 
 - originの扱いについて
 
7.3 まとめ
- [Column]アプリで利用している生体認証とパスキーは何が違うの?
 
第8章 パスキーのより高度な使い方
 ── より効果的な活用とUX向上方法を知ろう
8.1 パスキーの保存先パスキープロバイダを知る
8.2 パスキーが作成可能なことをパスキープロバイダやブラウザに知らせる
- AndroidのGoogleパスワードマネージャーの挙動
 
8.3 複数ドメインで同じRP IDのパスキーを利用可能にする
- ブラウザサポート状況とRelated Origin Requests利用判定方法
 - 類似する機能の補足
 - Related Origin Requests以外の実現方法
 
8.4 パスキーの表示名変更や削除をパスキープロバイダに通知する
- 見つからないパスキーを削除する
 - パスキーのリストを更新する
 - パスキーのユーザー名と表示名を更新する
 
8.5 より高いセキュリティのためのセキュリティキー
- セキュリティキーが求められるユースケース
 - セキュリティキーによる認証を強制するには
 
8.6 認証器の信頼性を証明するためのAttestation
- 認証器を判別するしくみ
 - Attestationの種類
 - Attestationの要求と検証方法
 - Attestation Objectを構成するパラメータ一覧
 
8.7 ユーザーがパスキーにアクセスできなくなったらどうする?
- パスキーだけではダメなのか
- パスキー以外の認証方法
 - ID連携
 - その他
 
 - アカウントリカバリの方法
- リカバリメール
 - リカバリコード
 - カスタマーサポートでの身元確認
 - デジタルアイデンティティ
 
 - 認証方法やアカウントリカバリに正解はない
 
8.8 まとめ
第9章 パスキー周辺のエコシステム
 ── 標準化の流れや開発者向け情報を確認しよう
9.1 パスキーの仕様を読み解くための手引き
- W3C(World Wide Web Consortium)
 - WebAuthn仕様の策定経緯
 - Credential Managementのクレデンシャルタイプ
- PasswordCredential ── パスワードを保存・取得するためのクレデンシャルタイプ
 - OTPCredential ── OTPを取得するためのクレデンシャルタイプ
 - FederatedCredential ── 連携済み外部Identity Providerを記憶するためのクレデンシャルタイプ
 - IdentityCredential ── 外部Identity Providerと連携するためのクレデンシャルタイプ
 - PublicKeyCredential ── 公開鍵クレデンシャルタイプ
 - navigator.credentials ── 各種クレデンシャルを扱うAPI
 
 - FIDOアライアンス
 - UAF
 - U2F
 - CTAP
 - FIDO関連仕様の一覧
 
9.2 パスキーの実装をサポートするエコシステム
- 認定プログラム
 - 開発者向けリソース
- 情報サイト
 - デモサイト
 - ライブラリ
 - メーリングリスト・コミュニティ