userVerification の詳細

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

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

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

ユーザー確認は、ユーザーの存在だけでなく、認証時に正しい人物がいたことを確認するためのオプションのセキュリティ レイヤです。スマートフォンでは、通常、生体認証、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 フラグが truefalse か、UV フラグが truefalse かを検証する必要があります。

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' を使用します。

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

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

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

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

userVerification='required' を使用するタイミング

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

このオプションのデメリットは、ログイン時にユーザーがより多くの手間を要する可能性があることです。たとえば、Touch ID が利用できない macOS では、ユーザーはシステム パスワードの入力を求められます。

userVerification='required' を使用すると、デバイスでユーザー認証が実行されることを保証できます。サーバーが UV フラグを true に設定していることを確認します。

まとめ

ユーザー確認を活用することで、パスキー リライング パーティはデバイス所有者がログインする可能性を測定できます。フォールバック ログイン メカニズムがユーザーフローに与える影響の重大性に応じて、ユーザー確認を必須にするか、任意にするかは、デベロッパーの判断に委ねられます。サーバーがパスキー ユーザー認証の UP フラグと UV フラグをチェックしていることを確認します。