WebAuthnのためのAuthenticator taxonomy仕様読解

created: 2018/09/27 22:16

相変わらずWebAuthnの仕様を読んでいる。

以前navigator.credentials.createについて仕様を読み進めていたところ、どうもAuthenticator Modelについて理解した方が全体を理解する上で捗りそうなので、
まずはAuthenticator taxonomy、つまりAuthenticatorの分類方法から読んでメモを残しておくことにした。

概要

まずAuthenticatorとは、公開鍵の生成やデータへの署名を行う存在で、Yubikey等がこれにあたる。
Authenticator Modelの章では、このAuthenticatorが満たすべき抽象化された振る舞いを定義していて、特にAuthenticator taxonomyでは、Authenticatorの実装に応じて、それらがどのような形式に分類されるかが明記されている。
この内容を理解しておくことで、諸々のAPIのパラメータの意味するところの理解がずっと楽になる。
(特にAuthenticator Selection Criteria)

Authenticatorの分類

Authenticatorを分類する上で、以下3つの形式

  • Authenticator Attachment Modality
  • Credential Storage Modality
  • Authentication Factor Capability

が、定義されており、それぞれにおいてAuthenticatorは適当な分類分けが成される。

APIのインターフェイスという点から見た場合、それぞれの形式はAuthenticatorSelectionCriteria(register時のAuthenticatorの絞り込みに使用する)の各プロパティをどのように決定するかに関係してくる。
このインターフェイスの持つ3つのプロパティ

  • authenticatorAttachment
  • requireResidentKey
  • userVerification

は、ちょうど先ほど挙げた3つの形式と1対1の関係にあるため、形式とその分類を理解しておくことでこれらの値を正しく設定するための理解が捗る。

Authenticator Attachment Modality

https://www.w3.org/TR/webauthn/#sctn-authenticator-attachment-modality

この形式では「Authenticatorとクライアントデバイス(ラップトップとか)が、物理的にどのように接続されているか」によってAuthenticatorが分類される。
分類には2種類あり、クライアントデバイス備え付けのAuthenticator(多分Touch IDなど? 手持ちのAuthenticatorがどのように分類されているかを知る術がありません...)のことをplatform attachmentと分類する。

対してBluetoothなど、標準化され、かつリムーバブルな方式でクライアントデバイスと通信するAuthenticatorはcross-platform attachmentに分類される。

この分類をAPI上で表現するための定数として、AuthenticatorAttachmentが定義されており、値もずばりそのまま"platform""cross-platform"の2つとなっている。

AuthenticatorSelectionCriteriaauthenticatorAttachmentはこのAuthenticatorAttachment定数を要求するため、
registerに使用するAuthenticatorをこの形式でもって絞り込みたい場合は適当な値どちらかを指定すると良い。

Credential Storage Modality

https://www.w3.org/TR/webauthn/#sctn-credential-storage-modality

仕様上、Authenticatorは、署名等に使用するクレデンシャル情報をPublic Key Credential Sourceで定義される構成で保存しており、それぞれはユニークなID(Credential ID)を持っている。
この形式では「Authenticatorがクレデンシャル情報をどこに保存するか」によってAuthenticatorが分類される。
分類方法としては以下の2種類が定義されている。

1つはclient-side credential storage modalityと呼ばれており、Authenticatorがクレデンシャル情報を、Authenticator自身あるいはクライアントデバイスに保存する場合がこれに該当する。
この分類のAuthenticatorによって管理されるクレデンシャル情報は、別名Resident Credentialと呼ばれる。

もう一方はserver-side credential storage modalityと呼ばれる形式で、こちらは中々トリッキーに感じる。

先ほど「クレデンシャル情報(Public Key Credential Source)はCredential IDというユニークなIDを持つ」と書いた。
ユニークなIDというと、無作為に選ばれた意味のないバイト列のような印象を受けるし、事実client-side credential storage modalityに分類されるAuthenticatorではそうなっている。

しかしserver-side credential storage modalityではそうではなく、これに分類されるAuthenticatorの場合、クレデンシャル情報を
暗号化し、それをそのままCredential IDとしてしまう。

そしてそれをAuthenticatorやクライアントデバイスには保存せずRelying Partyに提供する(Relying Partyに提供すること自体は、client-side credential storage modalityでも同様)。

Authenticatorでクレデンシャル情報を必要とする場合、まずはRelying PartyからCredential IDを受け取り、復号化し、その結果をクレデンシャル情報として使用する。

つまり実質的にクレデンシャル情報を保存する責任はRelying Partyが負うことになり、そのために"server-side"という命名がされているものと思われる。
メリットとして、管理可能なクレデンシャル情報数が、Authenticatorやクライアントデバイスのストレージの制限を受けないことが挙げられている。

WebAuthnのAPIにおいては、「client-side credential storage modalityに分類されるAuthenticatorのみを使用するかどうか(Resident Credentialの使用を強制するかどうか)」が指定可能となっており、
強制したい場合はAuthenticatorSelectionCriteriarequireResidentKeytrueにすることで指定可能となっている。

Authentication Factor Capability

最後の形式では、「Authenticatorがいくつの認証方式をサポートするか」によって分類が成される。
ここでいう「認証方式」とは、https://pages.nist.gov/800-63-3/sp800-63-3.html#afにて定義されている、

  • 所持していること(something you have - 物理的なデバイス, 鍵を所持していること、等)
  • 知っていること(something you know - パスワードを知っていること、等)
  • 本人であること(something you are - 生体認証、等)

のことである。
全てのAuthenticatorは、WebAuthnの利用者がそれを使って署名等を行うわけであるから、"something you have"の条件を満たしている。
ここで、Authenticatorによってはさらに追加の認証方式(PINの入力や生体認証)をサポートしている場合があり、そのようなAuthenticatorはmulti-factor capableと分類される。
反対に、そういった追加の認証方式を持たないAuthenticatorはsingle-factor capableと分類される。

WebAuthnのAPIにおいては、「multi-factor capableに分類されるAuthenticatorのみを使用し、追加の認証(user verificationと呼ばれる)を行うかどうか」が指定可能となっており、
強制したい場合はAuthenticatorSelectionCriteriauserVerificationに、UserVerificationRequirement定数で定義されている適当な値を指定する。
"required"なら必須、"preferred"なら任意となる。

所感

  • APIを眺めただけでは設定方法がさっぱりわからないような値も、このあたりのドキュメントを読むとかなり理解が進むイメージ
  • 他にもAuthenticator operationsなどは、APIに指定する値の妥当性を検討する上で重要そう
  • server-side credential storage modalityなAuthenticator、あまり扱いたくないな...
    • 暗号化されているとはいえ保存したくない
    • そもそもCredential IDのサイズがデカそう(どこに保存するか?