userVerification の詳細

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

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

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

macOS の iCloud キーチェーンで表示されるユーザー確認ダイアログのスクリーンショット。ダイアログには、認証をリクエストしたオリジンとユーザー名が表示され、Touch ID を使用してログインするようユーザーに求めるメッセージが表示されます。ダイアログの右上には [キャンセル] ボタンがあります。
macOS の iCloud キーチェーンでのユーザー確認ダイアログ。
Android 版 Chrome のユーザー確認ダイアログのスクリーンショット。ダイアログには、顔認識または指紋検出を使用して本人確認を行うようユーザーに求めるメッセージが表示され、認証をリクエストした送信元が表示されます。左下に、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」というラベルが付いた、考えられるフラグのリストが表示されます。
公開鍵認証情報の認証システム データ フィールド。

パスキーの登録と認証では、サーバーは UP フラグが true であること、および UV フラグが要件に応じて true または false であることを確認する必要があります。

userVerification パラメータの指定

WebAuthn 仕様に従い、RP は認証情報の作成とアサーションの両方で userVerification パラメータを使用してユーザー確認をリクエストできます。'preferred''required''discouraged' のいずれかを指定します。それぞれ次のように意味します。

  • 'preferred'(デフォルト): デバイスでユーザー確認方法を使用することを推奨しますが、使用できない場合はスキップできます。レスポンス認証情報には、ユーザー確認が行われた場合は UV フラグ値が true、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 に対応していない、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 フラグをチェックしていることを確認します。