-
Notifications
You must be signed in to change notification settings - Fork 0
MS_WebAuthnImplementation
- 戻る(Web Authentication API)
- WebAuthnを実装する。
- fido2-net-lib
- Web Authentication API(旧)
- FIDO認証器
- WebAuthnを実装する前に理解を深める。
- spec レベルは上位項を参照のこと。
以下に、各種、調査結果をサマリーする(まだまだ理解不足です)。
補足(登録と認証は同じ形をしている): 以降の登録フロー・認証フローは、
どちらも 「(1) challenge を受け取る → (2)(3) ブラウザ API を呼ぶ →
(4)(5)(6) サーバで検証する → (7) 保存/更新する」という同じ骨格になっている。
違いは、登録が公開鍵を受け取って保存するのに対し、
認証は保存済みの公開鍵で署名を検証する点だけである。
| # | パラメタ | 必須 / 任意 | 説明 | フォーマット |
|---|---|---|---|---|
| 1 | rp | 必須 | Relying party に関する情報 | JSON Object (下記メンバを持つ) |
| 1-1 | ・ id | 〃 | FQDN名 | String |
| 1-2 | ・ name | 〃 | 任意の RP サイト名 | String |
| 2 | user | 必須 | Credential が紐づくユーザー情報 | JSON Object (下記メンバを持つ) |
| 2-1 | ・ id | 〃 | RP 上のユーザ ID | ArrayBuffer |
| 2-2 | ・ name | 〃 | RP 上のユーザ ID | String |
| 2-3 | ・ displayName | 〃 | RP 上のユーザ表示名 | String |
| 3 | challenge | 必須 | サーバーで生成した乱数 | ArrayBuffer |
| 4 | pubKeyCredParams | 必須 | Credential 情報 | JSON Object の配列 |
| 4-1 | ・ type | 〃 | タイプ(public-key 固定) |
String |
| 4-2 | ・ alg | 〃 | アルゴリズムを表す数値 | Int |
| 5 | timeout | 任意 | ユーザーの入力待機時間 | Int |
| 6 | attestation | 任意 | Authenticator 自体の検証 | JSON Object (AttestationConveyancePreference) |
| 7 | authenticatorSelection | 任意 | 認証器への要求事項 | JSON Object (AuthenticatorSelectionCriteria) |
| 8 | excludeCredentials | 任意 | JSON Object (PublicKeyCredentialDescriptor) |
移行メモ(表の体裁): 元ページの表は PukiWiki の
セル結合(|>|・|~|)を使った階層表現だったが、
GitHub の Markdown はセル結合に対応していないため、
#の採番と・のインデントで階層を表し、
縦方向の結合は〃に置き換えた(以降の表も同様)。
補足(
user.idは個人情報を入れない): 表の2-1 user.idは
認証器の中に保存され、そのまま返ってくる値である。
メール アドレスなど推測・特定が可能な値を入れてはならず、
ランダムなバイト列(内部 ID)を使う、というのが仕様上の要求である。
表で2-2 nameの説明が2-1 idと同じ「RP 上のユーザ ID」に
なっているのは元ページのままだが、
実際にはnameは表示・識別用の文字列(ログイン名など)である。
| # | パラメタ | 説明 | フォーマット |
|---|---|---|---|
| 1 | id | 割り当てられた id | rawId の文字列表現 |
| 2 | rawId | id の ArrayBuffer 版 | ArrayBuffer |
| 3 | ・ response | AuthenticatorAttestationResponse | JSON Object (AuthenticatorAttestationResponse) |
| 3-1 | ・ attestationObject | 公開鍵などを含む | CBOR 形式 |
| 3-1-1 | ・ fmt | Attestation format | "fmt": "packed" |
| 3-1-2 | ・ authData | Raw buffer struct containing user info | "authData": "{rpIdHash: "..." ,... }" |
| 3-1-2-1 | ・ rpIdHash | ||
| 3-1-2-2 | ・ flags | ||
| 3-1-2-3 | ・ flagsBuf | ||
| 3-1-2-4 | ・ counter | ||
| 3-1-2-5 | ・ counterBuf | ||
| 3-1-2-6 | ・ aaguid | ||
| 3-1-2-7 | ・ credID | ||
| 3-1-2-8 | ・ credIDLen | ||
| 3-1-2-9 | ・ credIDLenBuf | ||
| 3-1-2-10 | ・ COSEPublicKey | ||
| 3-1-3 | ・ attStmt | Attestation statement data | "attStmt": {sig: "", x5c: ""} |
| 3-1-3-1 | ・ sig | Signature | "sig": "..." |
| 3-1-3-2 | ・ x5c | X.509 Certificate Chain | "x5c": ["..."] |
| 3-2 | ・ clientDataJSON | クライアント・データ | CBOR 形式 |
| 3-2-1 | ・ challenge | Random number | "challenge": "..." |
| 3-2-2 | ・ origin | Origin of the website | "origin": "http(s)://..." |
| 3-2-3 | ・ type | Type of the call | "type": "webauthn.create" |
| 4 | type | pubKeyCredParams - type と同じ | "type": "public-key" |
移行メモ(正誤):
clientDataJSONのフォーマットが
「CBOR 形式」となっていたが、名前のとおり
UTF-8 の JSON をそのまま入れた ArrayBuffer である
(CBOR なのは同じ階層のattestationObjectのほう)。
後述の認証フローの表では ArrayBuffer と書かれており、そちらが正しい。
-
techblogyahoo
clientDataJSON の...
-
fido2-net-lib ... サーバー側で処理
-
- UP : User Presence
ユーザーの存在確認(必須) - UV : User Verification
ユーザーの認証(任意)
- UP : User Presence
補足(UP と UV の違い): UP は「人がそこにいて操作した」ことの確認
(タッチしただけでも立つ)で、UV は「その人が本人である」ことの確認
(PIN や生体認証を通った)である。
パスワードレス(1 要素で完結)にしたい場合は UV が必須、
2 要素目としてのみ使う場合は UP だけでよい、という使い分けになる。
-
fido2-net-lib ... サーバー側で処理
-
-
fido2-net-lib ... サーバー側で処理
-
COSE から公開鍵を取り出して、保存する。
| # | パラメタ | 必須 / 任意 | 説明 | フォーマット |
|---|---|---|---|---|
| 1 | challenge | 必須 | サーバーで生成した乱数 | ArrayBuffer |
| 2 | timeout | 任意 | ユーザーの入力待機時間 | Int |
| 3 | rpId | 任意 | rpId の指定(登録時と同じ値を指定) | String |
| 4 | allowCredentials | 任意 | ユーザに紐づく Credential のリスト | Array (PublicKeyCredentialDescriptor) |
| 5 | userVerification | 任意 | ユーザ検証に関する要件 | String (enum UserVerificationRequirement) |
| # | パラメタ | 説明 | フォーマット |
|---|---|---|---|
| 1 | id | 割り当てられた id | rawId の文字列表現 |
| 2 | rawId | id の ArrayBuffer 版 | ArrayBuffer |
| 3 | response | assertion data | JSON Object (AuthenticatorAssertionResponse) |
| 3-1 | ・ authenticatorData | rpIdHash, flagsBuf, flags, counter, counterBuf | ArrayBuffer |
| 3-2 | ・ clientDataJSON | クライアント・データ | ArrayBuffer |
| 3-2-1 | ・ challenge | Random number | "challenge": "..." |
| 3-2-2 | ・ origin | Origin of the website | "origin": "http(s)://..." |
| 3-2-3 | ・ type | Type of the call | "type": "webauthn.get" |
| 3-3 | ・ signature | 署名の値 | ArrayBuffer |
| 3-4 | ・ userHandle | 認証器が返す値 | ArrayBuffer |
| 4 | type | タイプ(public-key 固定) |
String |
| 5 | getClientExtensionResults | extensions results struct |
移行メモ(正誤): 上表の
typeの例が
登録フローと同じ"webauthn.create"になっていたが、
認証(navigator.credentials.get())では"webauthn.get"である。
直後の「(4) challenge、origin、type の検証」でも
同じ写し誤りがあるが、そちらは元ページの記述を残した。
-
techblogyahoo
clientDataJSON の...
- fido2-net-lib ... サーバー側で処理
-
techblogyahoo
authenticatorData.flags- UP : User Presence
ユーザーの存在確認(必須) - UV : User Verification
ユーザーの認証(任意)
- UP : User Presence
-
fido2-net-lib ... サーバー側で処理
-
- Authenticator の検索
- PublicKey の取得
- signature を検証
- counter の検証と更新
FIDO2 サーバ標準は存在しないが、
-
FIDO2 適合テストツールで使用する提案された REST API の I/F は存在する。
-
この I/F は必須で無いが、Server が標準の方法で Message を送受信することで
適合テストツールによって使用され、機能が自動的に検証されるようにできる。 -
問題点
-
登録フローには、認証が必要だと思うのだケド、
認証実装したらテストツールも通らないんじゃないか?と。 -
以下のサーバ実装パターン毎、実際の実装は変わってきそう。
「RP & BaaSが実装」に書いたように、
Resource Server として動作する
BaaS 上に実装する方式に適合しそう。
-
-
参考
- Server Requirements and Transport Binding Profile
https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html
- Server Requirements and Transport Binding Profile
- https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html#example-credential-creation-options
- https://gist.github.com/daisukenishino2/f09fb400fa2186aead4b6f8cad59ab38#file-1-response-from-makecredentialoptions-webapi-json
- https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html#example-authenticator-attestation-response
- https://gist.github.com/daisukenishino2/f09fb400fa2186aead4b6f8cad59ab38#file-4-request-to-makecredential-webapi-json
- https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html#authentication-example-credential-get-options
- https://gist.github.com/daisukenishino2/f09fb400fa2186aead4b6f8cad59ab38#file-6-request-to-assertionoptions-webapi
- https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html#authentication-example-authenticator-assertion-response
- https://gist.github.com/daisukenishino2/f09fb400fa2186aead4b6f8cad59ab38#file-a-request-to-makeassertion-webapi-json
OIDC の STS/IdP(OP)、Client(RP) のどちらでも
WebAuthn の Relying Party(RP) になれる。
-
IdP/Sts に集約可能で楽。
-
提案された I/Fの実装
- 登録フロー
認証アクセスが必要だが、サイト内なので WebAPI よりポストバックがイイ - 認証フロー
認証後に画面遷移が必要なので WebAPI よりポストバックがイイ
- 登録フロー
-
折衷案
- RP が WebAuthn を操作し、
- バックエンドの IDaaS -> BaaS を使用して公開鍵を管理する。
-
提案された I/Fの実装
- 登録フロー
RP は、IdP/Sts と連携し、
Resource Server として機能する BaaS に公開鍵を登録。 - 認証フロー
BaaS に登録した公開鍵を取得するために、
Client 認証のみのグラント種別を使用し RP の認証をする。
- 登録フロー
-
IdP/Sts
- のコントロールが効かない場合。
- を、そもそも、保有しない場合。
-
提案された I/Fの実装
IdP/Stsが実装の実装と同様。
補足(rpId の制約が実装パターンを縛る): WebAuthn の鍵は
rpId(ドメイン)に紐づくため、
登録したドメインと異なるドメインからは使えない。
上記の 3 パターンが分かれるのは、
「どのドメインでnavigator.credentials.*を呼ぶか」と
「公開鍵をどこに置くか」を分離できるかどうかの違いによる。
- FIDO認証によるパスワードレスログイン実装入門 > デモ
https://www.slideshare.net/techblogyahoo/fido-124019677/29
-
準備
- navigator.credentials.create() メソッド → Web Authentication API
- navigator.credentials.get() メソッド → Web Authentication API
https://gist.github.com/daisukenishino2/f09fb400fa2186aead4b6f8cad59ab38#gistcomment-2852202
- Introduction to WebAuthn API
https://medium.com/@herrjemand/introduction-to-webauthn-api-5fd1fb46c285
- WebAuthnことはじめ
https://tech.mercari.com/entry/2019/06/04/120000
- Webauthn における ResidentKey と UserVerification について
https://blog.haniyama.com/2018/10/19/webauthn-residentkey/ - WebAuthn の Attestation
https://blog.haniyama.com/2018/11/19/webauthn-attestation/
- FIDOによるChromeとMacBook Proのtouch idを利用したパスワードレスログインの実装
https://qiita.com/ifsec_56/items/0cc5f1d73e7d2e3029ad
-
WebAuthn カテゴリーの記事一覧
https://ritou.hatenablog.com/archive/category/WebAuthn -
OpenID Connect のあれが WebAuthn のこれになったらどうなるかって話
https://ritou.hatenablog.com/entry/2018/09/28/032327- OIDC OP == WebAuthn RP
- OIDC RP == WebAuthn RP
- WebAuthn の利用/実装パターンを考える - Qiita
https://qiita.com/ritou/items/e32239dd482e8dc765d6
Tags: IT国際標準, 認証基盤
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。