パスキー
従来の パスワード認証 に代わる新しい認証方式
FIDO アライアンス と W3C が共同で標準化した技術に基づいている
FIDO はファイドって読むらしい radish-miyazaki.icon
FIDO2: 生体認証に 公開鍵暗号方式 を用いる パスワードレス認証 技術
以下の 2 つの仕様から成り立つ
WebAuthn: FIDO2 認証を Web ブラウザ経由で利用するための API 仕様
W3C が策定
CTAP: 認証器と Web ブラウザ間の 通信プロトコル
FIDO アライアンスが策定
認証器: 秘密鍵を生成・保管し、生体認証 や PIN で本人を行うデバイスや機能(e.g. iPhone)
これにより、ユーザはパスワードを入力する代わりに 生体認証 や PIN を使ってサービスにログインできる
処理フロー
大きく「登録」と「認証」の 2 つに分けられる
登録フロー
https://gyazo.com/afa10d5d371c302b4b3f8fb0820d3cda
Relaying Party(RP): ユーザがログインしようしているアプリケーション
https://w3c.github.io/webauthn/#sctn-api
より詳細なフロー
code:mermaid
sequenceDiagram
autonumber
participant User as ユーザー
participant Auth as 認証器
participant Browser as ブラウザ
participant RP as RPサーバ
User->>Browser: パスキー登録要求
Browser->>RP: 登録要求とユーザー情報送付
RP->>RP: PublicKeyCredentialCreationOptions作成
RP->>Browser: PublicKeyCredentialCreationOptions返却
Browser->>Auth: PublicKeyCredentialCreationOptionsをセットして、<br/>navigator.credentials.create() 実行
Auth->>User: ユーザー検証要求
User->>Auth: ユーザー検証のための情報入力
Auth->>Browser: 鍵ペア作成、<br/>PublicKeyCredential返却
Browser->>RP: PublicKeyCredential返却
RP->>RP: アテステーション(認証器が信頼できる正規のデバイスであることを)検証<br/>公開鍵登録
RP->>Browser: 登録処理完了通知
Browser->>User: 登録処理完了通知
(上図は Software Design 2025年1月号 から引用したものを一部改変)
PublicKeyCredentialCreationOptions
navigator.credentials.create() 渡すオブジェクト
登録処理に必要なプロパティが含まれる
主なプロパティ
table:_
プロパティ名 概要
challenge 推測が難しいランダムな文字列。16 Byte 以上推奨。
rp.id RP の識別子
rp.name RP の名前
user.id ユーザの識別子
uesr.name ユーザ名
user.displayName ユーザの表示名
pubKeyCredParams.aig 利用する 暗号化アルゴリズム の型番号
pubKeyCredParams.type 公開鍵の型(public-key 固定)
navigator.credentials.create()
CredentialsContainer インタフェースのメソッド
WebAuthn を介して、認証器に鍵ペア作成をリクエストする
認証器は秘密鍵を内部に保持し、公開鍵を PublicKeyCredential として返却する
PublicKeyCredential
navigator.credentials.create と後述する get の両方から返されるオブジェクト
Credential インタフェースを継承
主なプロパティ
table:_
プロパティ名 概要
id 公開鍵の識別子
rawID 識別子のバイナリデータ
response create の場合: AuthenticatorAttestationResponse
get の場合: AuthenticatorAssertionResponse
AuthenticatorAttestationResponse
認証器が「正規の認証器である」ことを証明するアステーションデータを含む
主なプロパティ
table:_
プロパティ名 概要
attestationObject 認証器の証明書・署名・公開鍵を含む CBOR エンコードデータ
clientDataJSON ブラウザが生成したコンテキスト情報
認証フロー
https://gyazo.com/b8be0a4bfb8ff0beae390fe1a0ea85c5
https://w3c.github.io/webauthn/#sctn-api
より詳細なフロー
code:mermaid
sequenceDiagram
autonumber
participant User as ユーザー
participant Auth as 認証器
participant Browser as ブラウザ
participant RP as RPサーバ
User->>Browser: パスキー認証要求
Browser->>RP: 認証要求とユーザー情報送付
RP->>RP: PublicKeyCredentialRequestOptions作成
RP->>Browser: PublicKeyCredentialRequestOptions返却
Browser->>Auth: PublicKeyCredentialRequestOptionsを引数にセットして、<br/>navigator.credentials.get() 実行
Auth->>User: ユーザー検証要求
User->>Auth: ユーザー検証のための情報入力
Auth->>Browser: アサーション作成、<br/>PublicKeyCredential返却
Browser->>RP: PublicKeyCredential返却
RP->>RP: アサーション(ユーザが秘密鍵を持っている本人であることを)検証<br/>認証確認
RP->>Browser: 認証処理完了通知
Browser->>User: 認証処理完了通知
(上図は Software Design 2025年1月号 から引用したものを一部改変)
PublicKeyCredentialRequestOptions
navigator.credentials.get() に渡すオブジェクト
認証処理に必要なプロパティが含まれる
主なプロパティ
table:_
プロパティ名 概要
challenge 推測が難しいランダムな文字列。16 Byte 以上推奨。
rpid RP の識別子、ドメイン情報
allowCredentials.id RP がサポートする資格情報の識別子
allowCredentials.type 公開鍵の型(public-key 固定)
navigator.credentials.get()
CredentialsContainer インターフェースのメソッド
WebAuthn を介して、認証器に既存の 認証情報 を使った 署名 の生成をリクエストする
認証器はユーザ検証後、秘密鍵で challenge に署名し、PublicKeyCredential として返す
AuthenticatorAssertionResponse
認証器が秘密鍵で署名したアサーションデータを含む
主なプロパティ
table:_
プロパティ名 概要
authenticatorData 認証器の状態情報
clientDataJSON ブラウザが生成したコンテキスト情報
signature 秘密鍵による認証
userHandle ユーザ識別子
サンプルコード
GitHub.icon https://github.com/radish-miyazaki/passkey-demo-golang
RPサーバ側の実装の大部分は go-webauthn に委譲
参考
公式
https://w3c.github.io/webauthn/
https://fidoalliance.org/passkeys
書籍
Software Design 2025年1月号
記事
https://hanesol.com/blog_passkey
https://www.nri-digital.jp/tech/20230124-12533/
https://zenn.dev/hakoten/books/c9718954916f82
https://qiita.com/kandu/items/589f84a451c976a23fe1