Skip to content

MS_WebAuthenticationAPI

nishi_74322014 edited this page Aug 12, 2026 · 3 revisions

Web Authentication API

概要

  • Web Authentication API (WebAuthn) は

    • FIDO2 の Web Application 用 JavaScript API。
    • 公開鍵暗号を用いた認証を行う Credential Management API の拡張機能
    • パスワードを用いない認証に加え、SMS を用いない二要素認証を実現する。
  • 昔のサンプルは、makeCredential & getAssertion() メソッド
    (Web Authentication API(旧)(MS_WebAuthenticationAPIOld.md))だったが、
    最近のサンプルは、navigator.credentials.create & get() メソッドに変わっている。

補足(最新化:現在の位置づけ): 元ページ執筆時点では
「新しい仕様」だったが、現在は次の状態にある。

状態
WebAuthn Level 1 2019 年 3 月 W3C 勧告
WebAuthn Level 2 2021 年 4 月 W3C 勧告
WebAuthn Level 3 策定中(勧告候補)

主要ブラウザ・OS はすべて対応済みで、
2022 年以降は パスキー(Passkey) という名前で一般に普及した。
パスキーは新しい規格ではなく、
発見可能なクレデンシャル(後述の Resident Credential)を、
OS / ブラウザのアカウントで同期する運用
」に付いた呼称である。

詳細

  • W3C で定義されている使用する(主な)API の名前は、

    • navigator.credentials.create() メソッド
    • navigator.credentials.get() メソッド
  • セキュアコンテキスト(https or localhost)であることを必要とし、
    ブラウザがセキュアコンテキストで動作していない場合は利用できない。

  • 冒頭のユースケースでは、
    デスクトップのブラウザで操作して、
    登録(Registration で Attestation)と認証(Authentication で Assertion)
    だけをスマホに転送するというユースケースが紹介されている。

補足: このユースケースは現在
**クロスデバイス認証(CDA / hybrid transport)**として実現されている。
PC 側に QR コードを表示し、スマホで読み取って BLE で近接を確認したうえで、
スマホ内の認証器で署名する。
BLE による近接確認があるため、遠隔の攻撃者に QR を転送されても成立しない。

登録(RegistrationでAttestation)

  • navigator.credentials.create() メソッドを呼び出す。

  • publicKey オプションと併用する。

    • 引数:PublicKeyCredentialCreationOptions
    • 戻り値:AuthenticatorAttestationResponse

認証(AuthenticationでAssertion)

  • navigator.credentials.get() メソッドを呼び出す。

  • publicKey オプションと併用する。

    • 引数:PublicKeyCredentialRequestOptions
    • 戻り値:AuthenticatorAssertionResponse

仕様

登場人物

  • ユーザの登録(Registration で Attestation)と
    認証(Authentication で Assertion)をする。

  • Relying Party Identifier (RP ID):

    • WebAuthn Relying Party を識別する有効なドメイン文字列
    • スキームには https が必要(ポート番号に制限はない)。
    • FQDN 名か、ドメイン接尾辞の何れかになる。
      https://login.example.com:1337 なら、
      • FQDN 名: login.example.com
      • ドメイン接尾辞: example.com
  • RP の実装パターン(WebAuthnを実装する。(MS_WebAuthnImplementation.md))

補足(RP ID の設計は後から変えられない): クレデンシャルは
RP ID に紐づけて認証器に保存される
login.example.com で登録した鍵は、
RP ID を example.com に変えると使えなくなる(再登録が必要)。

したがって、サブドメインを跨いで使う可能性が少しでもあるなら、
最初から登録可能なドメイン接尾辞(example.com)を RP ID にする
逆に、サブドメインを信用できない環境では広く取ってはならない。

Level 3 では relatedOrigins により
複数ドメイン(example.jp / example.com など)から
同一 RP ID を使う道が用意されつつある。

認証器(Authenticator)

  • 認証器アテステーション(Authenticator Attestation)

    • 認証器のデータを検証する作業。
      • 製造と機能
      • 認証器が発行する Credential Public Key、Credential ID、署名カウンタ
    • アテステーション証明書: アテステーションするために使用する秘密鍵を含む
      X.509証明書
  • 式(Ceremony)

    • 登録式(Registration Ceremony)に従い、登録を行うと、
      アテステーション(Attestation)が発行される。
    • 認証式(Authentication Ceremony)に従い、認証を行うと、
      認証器アサーションが発行される。
  • レート制限

    • ブルートフォース攻撃に対する制御を実装するプロセス。
    • 限度に達すると、
      • 指数関数的に増加する遅延を課すか、
      • または現在の認証方式を無効にし、
      • 利用可能であれば異なる認証係数を提供する。

クライアント

  • ブラウザ実装など。
  • ユーザエージェントに(全体的にまたは部分的に)実装された中間的なエンティティ

仕組み

  • 登録(Registration で Attestation)と
  • 認証(Authentication で Assertion)は

儀式であり、この儀式では、

  • ユーザ
  • 依拠当事者
  • 認証器
  • クライアント

が共同した、

ユーザの存在またはユーザ確認のテスト(式典)

が必要になる。

各種鍵(Credential)

  • Credential ID

  • Credential Public Key

    • 登録時に認証器によって生成され、
      依拠当事者(Relying Party)に返された信用証明書の公開鍵部分
    • 信用証明書の公開鍵は、FIDO UAF、FIDO U2F、それに関連する
      本仕様書の一部において、User Public Key と呼ばれる。
  • Resident Credential(Client-side-resident Public Key Credential Source)
    FIDO2 から新しく追加された、キーの中にユーザ情報を保存する機能。

    • navigator.credentials.create() メソッドの引数の
      PublicKeyCredentialCreationOptions の、
      authenticatorSelectionrequireResidentKey: true をセットすると
      認証器に格納される。
    • ユーザ情報(Credential ID、PublicKeyCredentialUserEntity
      Challenge への署名に必要な情報)が保存される。
    • navigator.credentials.get() メソッドで Challenge だけで
      (ユーザ情報を入力しないで)ログインができる。
    • Resident Credential を登録する認証器の容量制限がある。
    • ユーザ・ハンドル + RP ID で信用証明書を選択できる。
    • 参考:
      https://blog.haniyama.com/2018/06/17/edge-support-webauthn/#resident-key-toha

移行メモ(正誤・最新化): 元ページのオプション名は
requiredResidentKey となっていたが、正しくは requireResidentKey(末尾 d なし)。

さらに Level 2 以降、この語彙は次のように置き換わっている。

Resident Credential Discoverable Credential(発見可能なクレデンシャル)
requireResidentKey: true residentKey: "required""preferred" / "discouraged" も可)

requireResidentKey は後方互換のため残っているが、
新規実装では residentKey を使う。
パスキーとは、この Discoverable Credential を同期させたものである。

ユーザの存在またはユーザ確認のテスト(式典)

登録と認証では、以下のような存在 vs 認証を行う。

  • ユーザ存在テスト

    • ユーザが認証器と簡単に接触することによってブール結果が生成される。
    • ユーザ存在テストが正常に完了すると、ユーザは「UP: User Present」と言われる。
  • ユーザ検証

    • authenticatorMakeCredential + authenticatorGetAssertion で行われる。
    • ユーザ検証プロセスが正常に完了すると、ユーザは「UV: User Verified」と言われる。

補足(サーバ側で必ず検査する): UP / UV は
authenticatorDataflags バイト(bit 0 = UP、bit 2 = UV)に現れる。
userVerification: "required" を要求しただけでは不十分で、
サーバ側で UV フラグが立っていることを検証する必要がある。
ここを省くと、パスワードレス(単要素)認証として成立してしまう。

登録(RegistrationでAttestation)

  • 登録式(Registration Ceremony)

    • ユーザの存在またはユーザ確認のテスト(式典)
    • Credential Public Key を作成し、
      ユーザの依拠当事者(Relying Party)上のアカウントに関連付ける。
  • 認証器アテステーション(Authenticator Attestation)
    authenticatorMakeCredential 操作の結果として認証器から返された、
    署名された AuthenticatorAttestationResponse オブジェクト。

認証(AuthenticationでAssertion)

  • 認証式(Authentication Ceremony)

    • ユーザの存在またはユーザ確認のテスト(式典)
    • ユーザの依拠当事者(Relying Party)上の
      Credential Public Key で、認証器アサーションの署名を検証する。
  • 認証器アサーション(Authenticator Assertion)
    authenticatorGetAssertion 操作の結果として認証器から返された、
    署名された AuthenticatorAssertionResponse オブジェクト。

依存

データ

  • CBOR
  • CDDL(CBORを参照)
  • COSE
  • ArrayBuffer(DNET_ECMAScript.md

その他

  • HTML

  • DOM

  • ECMAScript

  • Web IDL: Web ブラウザーで実装するための API を記述するための IDL

  • FIDO AppID:
    呼び出し元アプリケーションの FacetID を決定し、呼び出し元の FacetID が
    AppID に対して許可されているかどうかを判断するアルゴリズムを定義する。

Credential Management API

登録(Attestation): navigator.credentials.create()メソッド

内部で、authenticatorMakeCredential を呼び出す。

引数:PublicKeyCredentialCreationOptions

  • 主要な引数

    • rp

      • id: RP ID
      • name: 文字列
    • user

      • id
      • name
      • displayName
    • challenge

      • ランダムな情報の大きなバッファー(例えば 100 バイト以上)が絶対に重要。
      • 登録過程のセキュリティを確保するためにサーバ上で生成する必要がある。
    • timeout

    • pubKeyCredParams

      // このRPはES256またはRS256の公開鍵を受け入れますが、ES256公開鍵を優先します。
      pubKeyCredParams:
      [
        {
          type: "public-key",
          alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
        },
        {
          type: "public-key",
          alg: -257 // Value registered by this specification for "RS256"
        }
      ],

補足(user.id の設計): user.id
ユーザ ハンドルとして認証器側に保存され、
発見可能なクレデンシャルでの認証時にサーバへ返ってくる。

  • メールアドレスやユーザ名を入れてはならない
    (認証器を入手した者に個人情報が漏れる。仕様上も禁止されている)。
  • 不変のランダムなバイト列(64 バイト以下)を使う。
    ユーザ名を変更しても鍵が使えるようにするため、
    内部の不変 ID をそのまま使うのが良い。

また challenge はサーバ側で生成し、
一度きり・短命であることをサーバ側で検証する(リプレイ防止)。

  • オプションの引数

    • attestation

      内容
      "none"(既定値) ユーザ名 / パスワードを FIDO2 に切り替える場合(FIDO2 はパスワードよりも優れていると考える場合)
      "indirect" スマートカードまたは UAF から移行する場合、認証器の信頼性を attestation statement から確認する必要がある。クライアントが attestation statement を取得する方法を決定できる
      "direct" 同上。サーバーが attestation statement を必要とすることを示す
    • authenticatorSelection
      色々なオプションを指定、その一つに Resident Key のサポートなどがある。

補足(attestation は基本 none でよい): アテステーションを検証すると
「どのメーカーのどの型番の認証器か」が分かるが、
引き換えに次のコストが生じる。

  • **FIDO MDS(Metadata Service)**を取得・更新し続ける運用が必要
  • プライバシー上の懸念があり、ブラウザが同意プロンプトを出す場合がある
  • パスキー(プラットフォーム認証器)では実質的に意味を持たない

「特定の認定済みハードウェアだけを許可する」という
企業・金融の要件がない限り、none のままでよい。

  • 参考
    • PublicKeyCredentialCreationOptions
      https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialcreationoptions

      dictionary PublicKeyCredentialCreationOptions {
         required PublicKeyCredentialRpEntity              rp;
         required PublicKeyCredentialUserEntity            user;
         required BufferSource                             challenge;
         required sequence<PublicKeyCredentialParameters>  pubKeyCredParams;
         unsigned long                                     timeout;
         sequence<PublicKeyCredentialDescriptor>           excludeCredentials = [];
         AuthenticatorSelectionCriteria                    authenticatorSelection;
         AttestationConveyancePreference                   attestation = "none";
         AuthenticationExtensionsClientInputs              extensions;
      };
      

戻り値:AuthenticatorAttestationResponse

厳密には、PublicKeyCredential.response に、
AuthenticatorResponse <- AuthenticatorAttestationResponse を含む、
PublicKeyCredential に解決する Promise を返す。

  • idrawId): Global に Unique な PublicKeyCredential の ID(credentialId

  • type: public-key(この UseCase では固定)

  • AuthenticatorAttestationResponse のプロパティ

    • clientDataJSON: ArrayBuffer 型、読み取り専用

      • AuthenticatorResponse から継承
      • 認証器の authenticatorMakeCredential() メソッドの戻り値
    • attestationObject: ArrayBuffer 型、読み取り専用
      idrawId)= PublicKeyCredential の ID(credentialId)に対応した、
      公開鍵と他の認証データ

      • authenticatorData
        https://www.w3.org/TR/webauthn/#sec-authenticator-data

        # Name Length (in bytes) Description
        1 rpIdHash 32 PublicKeyCredential に関連付けられた RP ID の SHA-256 ハッシュ
        2 flags 1 Flags (bit 0 is the least significant bit)
        3 signCount 4 署名カウンタ(32-bit unsigned big-endian integer)
        4 attestedCredentialData 可変(存在する場合) 検証された認証器アテステーション(存在する場合)
        5 extensions 可変(存在する場合) 拡張の認証器データ
      • fmt:アテステーションステートメントの形式を示すテキスト文字列
        "packed""tpm""android-key""android-safetynet""fido-u2f""none"

      • attStmtfmt で定義された形式のアテステーションステートメント

補足(サーバ側の検証項目): 登録時にサーバが確認すべき最低限は次の通り。

対象 検証内容
clientDataJSON.type "webauthn.create" であること
clientDataJSON.challenge 自分が発行した challenge と一致すること
clientDataJSON.origin 期待する Origin と完全一致すること
authenticatorData.rpIdHash 自分の RP ID の SHA-256 と一致すること
flags UP が立っていること(UV は要件次第)
公開鍵 pubKeyCredParams で許可した alg であること

origin の検証がフィッシング耐性の本体である。
認証器は RP ID にしか署名しないため、
偽サイトからは正規サイト向けのアサーションを作れない。

認証(Assertion): navigator.credentials.get()メソッド

内部で、authenticatorGetAssertion を呼び出す。

引数:PublicKeyCredentialRequestOptions

  • 主要な引数

    • challenge

      • ランダムな情報の大きなバッファー(例えば 100 バイト以上)が絶対に重要。
      • 認証過程のセキュリティを確保するためにサーバ上で生成する必要がある。
    • timeout

    • rpId

    • allowCredentials

      • type: "public-key"
      • id: idrawId)= PublicKeyCredential の ID(credentialId
      • transports: [](通信のヒントらしいが、空の配列が指定されている)
    • userVerification
      ユーザー検証要件の列挙型

      • "required"
      • "preferred"
      • "discouraged"

補足(allowCredentials を空にすると): allowCredentials
省略(空)にすると、発見可能なクレデンシャル(パスキー)だけが対象になり、
ユーザ名の入力なしでログインできる(Usernameless)。

Level 2 以降は、さらに Conditional UI(自動入力 UI)が使える。

if (await PublicKeyCredential.isConditionalMediationAvailable()) {
  navigator.credentials.get({ publicKey: opts, mediation: "conditional" });
}

フォームの autocomplete="username webauthn" と併せて使うと、
ID 入力欄のサジェストにパスキーが並ぶ。

戻り値:AuthenticatorAssertionResponse

厳密には、PublicKeyCredential.response に、
AuthenticatorResponse <- AuthenticatorAssertionResponse を含む、
PublicKeyCredential に解決する Promise を返す。

  • idrawId): Global に Unique な PublicKeyCredential の ID(credentialId

  • type: public-key(この UseCase では固定)

  • AuthenticatorAssertionResponse のプロパティ

    • clientDataJSON: ArrayBuffer 型、読み取り専用

      • AuthenticatorResponse から継承
      • 認証器の authenticatorGetAssertion() メソッドの戻り値
    • authenticatorData: ArrayBuffer 型、読み取り専用

    • signature: ArrayBuffer 型、読み取り専用

    • userHandle: ArrayBuffer 型、読み取り専用、nullable

補足(署名カウンタの扱い): authenticatorDatasignCount
「認証器の複製を検知する」ためのもので、
前回値より増えていることを検証するのが本来の使い方である。

ただし、パスキー(同期されるクレデンシャル)では
signCount は常に 0 になる
ことが多い。
複数端末で共有される以上、単調増加が保証できないためである。

したがって現在の実装指針は次の通り。

  • signCount が 0 のときは検査をスキップする
  • 0 以外で減少していた場合のみ、警告・追加認証などの対応をとる
  • 減少をもって即座にログイン拒否とすると、正常な利用を壊す

参考

w3c

MDN - Web APIs

Credential Management API

Web Authentication API

Credential Management API 中の PublicKeyCredential を拡張したもの。

webauthn.org

Auth0

仕組みをアニメーションで解り易く説明している。

移行メモ: 元ページの見出しは「OAuth0」だったが、
webauthn.me を運営しているのは Auth0(Okta 傘下)である。

Yubico

blog.jxck.io

enjoy struggling

ritou

ライブラリ

fido2-net-lib(MS_Fido2NetLib.md

.NET Standard の Web Authentication API 対応ライブラリ。

WebAuthn4J

Java の Web Authentication API 対応ライブラリ。
(日本のコミュニティが開発をしている)

内部リンク

  • Web Authentication API(旧)(MS_WebAuthenticationAPIOld.md
  • WebAuthnを実装する。(MS_WebAuthnImplementation.md

Tags: 移行, IT国際標準, 認証基盤

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally