userVerification の詳細

このドキュメントでは、WebAuthn の userVerification と、パスキーの作成時または認証時に userVerification が指定された場合のブラウザの動作について説明します。

WebAuthn の「ユーザー確認」とは何ですか?

パスキーは公開鍵暗号に基づいて構築されています。パスキーを作成すると、公開鍵 / 秘密鍵のペアが生成され、秘密鍵はパスキー プロバイダによって保存されます。公開鍵は証明書利用者(RP)サーバーに返され、保存されます。サーバーは、ペアの公開鍵を使用して、同じパスキーで署名された署名を検証することで、ユーザーを認証できます。公開鍵認証情報の「ユーザー表示」(UP)フラグは、認証中に誰かがデバイスを操作したことを証明します。

ユーザー確認は、認証時にユーザー プレゼンス アサート時に、特定の人物だけでなく正しい人物がいたことをアサートするオプションのセキュリティ レイヤです。スマートフォンでは、通常、画面ロック メカニズム(生体認証、PIN またはパスワード)を使用します。ユーザー確認が行われたかどうかは、パスキーの登録および認証時に認証システムデータに返される「UV」フラグで報告されます。

macOS の iCloud キーチェーンのユーザー確認ダイアログのスクリーンショット。このダイアログでは、ユーザーに Touch ID を使用してログインするよう求めるメッセージが表示され、認証を要求しているオリジンとユーザー名が表示されます。ダイアログの右上には、[キャンセル] ボタンがあります。
macOS の iCloud キーチェーンのユーザー確認ダイアログ
Chrome for Android のユーザー確認ダイアログのスクリーンショット。このダイアログでは、顔認識や指紋認証を使用して本人確認を行うようユーザーに求め、認証をリクエストしているオリジンを表示します。左下に、PIN を使用したオーナー確認のオプションがあります。
Android Chrome のユーザー確認ダイアログ

サーバーで UP と UV を検証する方法

ユーザー確認(UP)とユーザー確認(UV)のブール値フラグは、認証システム データ フィールドでサーバーに通知されます。認証時に、保存されている公開鍵を使用して署名を検証することで、認証システムのデータ フィールドの内容を検証します。署名が有効であれば、サーバーはフラグが本物であるとみなすことができます。

認証データ構造の図。左から右に、データ構造の各セクションは、「RP ID HASH」(32 バイト)、「FLAGS」(1 バイト)、「COUNTER」(4 バイト、ビッグエンディアン uint32)、「ATTESTE CRED」を読みます。DATA(存在する場合は可変長)、EXTENSIONS(存在する場合は可変長(CBOR))。「FLAGS」セクションを展開して、左から右にラベル「ED」、「AT」、「0」、「BS」、「BE」、「UV」、「0」、「UP」とラベル付けされた、潜在的なフラグのリストを表示します。
公開鍵認証情報の Authenticator データ フィールド。

パスキーの登録と認証の際、サーバーは要件に応じて、UP フラグが true であることと、UV フラグが truefalse かを調べる必要があります。

userVerification パラメータの指定

WebAuthn の仕様に従って、RP は認証情報の作成とアサーションの両方で userVerification パラメータを使用してユーザー確認をリクエストできます。'preferred''required'、または 'discouraged' を受け入れます。これは、それぞれ以下を意味します。

  • 'preferred'(デフォルト): デバイスでユーザーの確認方法を使用することが推奨されますが、利用できない場合はスキップできます。レスポンスの認証情報には、ユーザー確認が実行された場合は true の UV フラグの値が含まれ、UV が実行されなかった場合は false が含まれます。
  • 'required': デバイスで利用可能なユーザー確認メソッドを呼び出す必要があります。存在しない場合、リクエストはローカルで失敗します。つまり、レスポンスの認証情報は常に UV フラグが true に設定された状態で返されます。
  • 'discouraged': ユーザーの確認方法を使用することはおすすめしません。ただし、デバイスによっては、このままユーザー確認が実行されることがあり、UV フラグに true または false が含まれることもあります。

パスキー作成のサンプルコード:

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

パスキー認証のサンプルコード:

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

userVerificationさんにはどのオプションを選択すればよいですか。

使用する必要がある userVerification 値は、アプリの要件とユーザー エクスペリエンスのニーズによって異なります。

userVerification='preferred' を使用するケース

保護よりもユーザー エクスペリエンスを優先する場合は、userVerification='preferred' を使用します。

環境によっては、ユーザー確認が保護よりも煩わしくなることがあります。たとえば、Touch ID がサポートされていない macOS の場合(デバイスが Touch ID をサポートしていない、無効になっている、デバイスがクラムシェル モードになっているなど)、ユーザーは代わりにシステム パスワードを入力するよう求められます。これにより煩わしさが生じ、ユーザーが認証を完全に放棄する可能性があります。摩擦をなくすことの方が重要な場合は、userVerification='preferred' を使用してください。

Touch ID が利用できない場合に表示される macOS のパスキー ダイアログのスクリーンショット。ダイアログには、認証を要求しているオリジンやユーザー名などの情報が含まれます。ダイアログの右上には、[キャンセル] ボタンがあります。
Touch ID を使用できない場合に macOS に表示されるパスキー ダイアログ。

userVerification='preferred' の場合、ユーザー確認が正常に実行された場合は UV フラグが true になり、ユーザー確認がスキップされた場合は false になります。たとえば、Touch ID を使用できない macOS の場合、ユーザーはボタンをクリックしてユーザー確認をスキップするように求められ、公開鍵認証情報には false UV フラグが含まれます。

UV フラグをリスク分析のシグナルとして利用できます。他の要因でログイン試行が危険であると思われる場合は、ユーザー確認が行われていないために、追加のログイン確認をユーザーに示すことをおすすめします。

userVerification='required' を使用するケース

UP と UV の両方が絶対に必要な場合は、userVerification='required' を使用します。

このオプションの欠点は、ログイン時にユーザーが煩わしくなる可能性があることです。たとえば、Touch ID を使用できない macOS では、ユーザーはシステム パスワードを入力するよう求められます。

userVerification='required' を使用すると、デバイス上でユーザー確認を確実に実行できます。サーバーが UV フラグが true であることを確認します。

おわりに

ユーザー確認を利用することで、パスキーの証明書利用者はデバイス所有者がログインする可能性を測定できます。代替のログイン メカニズムがユーザーフローに与える影響の重要度に応じて、ユーザー確認を必須にするか、任意にするかを選択します。パスキーのユーザー認証について、サーバーが UP フラグと UV フラグをチェックすることを確認してください。