Featured image of post WebAuthnとパスキー:2024年のパスワードレス認証 Featured image of post WebAuthnとパスキー:2024年のパスワードレス認証

WebAuthnとパスキー:2024年のパスワードレス認証

WebAuthnとパスキーによるパスワードレス認証の実装ガイド。プラットフォーム対ローミング認証機、条件付きUI、ブラウザサポートを解説。

パスワードは数十年にわたってWeb認証の主要な仕組みでしたが、セキュリティとユーザビリティに多くの問題を抱えています。WebAuthn(Web Authentication)とパスキーエコシステムは、暗号学的に安全でフィッシング耐性のある認証を実現します。2024年現在、主要プラットフォームすべてがパスキーをサポートしており、パスワードレス認証を導入する絶好のタイミングです。

WebAuthnの理解

WebAuthnは公開鍵暗号ベースの認証を実現するW3C標準です。登録フローでは、サーバーが暗号学的チャレンジを送信し、認証機が鍵ペアを生成、公開鍵がサーバーに保存されます。認証フローでは、サーバーがチャレンジを送信し、認証機が秘密鍵で署名、サーバーが公開鍵で署名を検証します。

登録:  サーバー → チャレンジ → 認証機(鍵ペア生成) → 公開鍵 → サーバー
認証:  サーバー → チャレンジ → 認証機(秘密鍵で署名) → 署名 → サーバー(検証)

秘密鍵は認証機から外部に出ないため、フィッシング、クレデンシャルスタッフィング、サーバーサイドのデータベース侵害に対して本質的に耐性があります。


パスキーの概念

パスキーは発見可能なWebAuthn認証情報であり、ユーザーのデバイスに安全に保存され、iCloudキーチェーンやGoogleパスワードマネージャーなどの仕組みを通じてデバイス間で同期されます。パスキーはユーザーがサイトごとに管理でき、生体認証またはPINで保護され、QRコードによるクロスデバイス認証も可能です。従来の認証情報とは異なり、パスキーはエンドユーザーが直接管理できるように設計されています。


プラットフォーム認証機 vs ローミング認証機

プラットフォーム認証機はデバイスに内蔵されています(Touch ID、Windows Hello、Android生体認証)。ローミング認証機はUSB、NFC、Bluetooth経由で接続する外部セキュリティキー(YubiKey、Titan Key)です。セキュリティ要件とユーザーエクスペリエンスに基づいて選択します。

特徴プラットフォーム認証機ローミング認証機
入手性デバイス内蔵別途購入が必要
携帯性エコシステム内で同期物理的に携帯可能
セキュリティ良好非常に高い(ハードウェア)
UXシームレス(生体認証)キーの挿入が必要
クロスデバイスクラウド同期手動転送

条件付きUI

条件付きUIは、ログインフローでブラウザがパスキーの自動入力を提案できるようにします。ユーザーは保存済みパスワードと並んでパスキーオプションを自動入力ドロップダウンに表示され、変換率が大幅に向上します。

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

実装には3つの手順が必要です。mediation: "conditional"の設定、入力フィールドへのautocomplete="username webauthn"の追加、およびautofill処理の適切な実装です。この機能により、ユーザーが既に理解している自動入力エクスペリエンスにパスキー認証が統合されます。


JavaScriptによる実装

以下のコードは、WebAuthnの登録および認証フローの基本を示しています。

// 登録
const publicKeyCredential = await navigator.credentials.create({
  publicKey: {
    challenge: crypto.getRandomValues(new Uint8Array(32)),
    rp: { name: "My App", id: "example.com" },
    user: {
      id: crypto.getRandomValues(new Uint8Array(16)),
      name: "[email protected]",
      displayName: "User",
    },
    pubKeyCredParams: [{ alg: -7, type: "public-key" }],
    authenticatorSelection: {
      residentKey: "preferred",
      userVerification: "preferred",
    },
  },
});

// 認証
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: crypto.getRandomValues(new Uint8Array(32)),
    allowCredentials: credentials.map(cred => ({
      id: base64urlToBytes(cred.id),
      type: "public-key",
    })),
    userVerification: "preferred",
  },
});

サーバーサイドの検証では、attestationオブジェクトの解析、暗号署名の検証、オリジンとRP IDの一致確認が必要です。Node.js向けの@simplewebauthn/serverなどのライブラリを使用すると、この処理を大幅に簡略化できます。


セキュリティの考慮事項

WebAuthnはフィッシング、クレデンシャルスタッフィング、中間者攻撃、データベース侵害などの攻撃カテゴリ全体を排除します。ただし、適切な実装が不可欠です。オリジンがRP IDと一致することを確認し、暗号学的にランダムな使い捨てチャレンジを生成し、認証試行のレート制限を実装し、デバイス紛失時の復旧オプションを提供してください。移行期間中はパスワードフォールバックを維持し、パスワードログイン成功後の段階的パスキー登録(プログレッシブエンロールメント)を通じてユーザーの移行を促進します。


結論

パスキーは10年ぶりのWeb認証セキュリティの最も重要な改善です。主要プラットフォームがエコシステムをサポートし、ユーザーが生体認証にますます慣れている中、2024年はパスキーを採用する年です。実装の複雑さは中程度で、セキュリティとユーザーエクスペリエンスの利点は非常に大きいです。パスワードを排除することで、攻撃ベクター全体を排除しながら、よりスムーズな認証体験をユーザーに提供できます。