Passkeys / WebAuthn 入門 - パスワードレス認証を管理画面に入れる前に知っておくこと

Passkeys / WebAuthn 入門 - パスワードレス認証を管理画面に入れる前に知っておくこと

作成日:
更新日:

パスワードは、使い回し・漏洩・フィッシングと、弱点だらけの認証方式です。その置き換えとして実用段階に入ったのがパスキー(Passkeys)、その土台が Web Authentication API(WebAuthn)です。

この記事では、パスキー / WebAuthn の仕組みを公開鍵暗号の観点から整理し、「自分のサービスの管理画面に入れるべきか」を判断するための材料(フィッシング耐性・復旧手段・MFAとの違い)までをまとめます。

パスキーとは何か

パスキーは、パスワードの代わりに公開鍵暗号で認証する仕組みです。WebAuthn を使って実装されます。

仕組みの核はシンプルです。

  • 登録時に、デバイス(認証器)が鍵ペア(秘密鍵・公開鍵)を生成する
  • 秘密鍵はデバイスから出ない。サーバには公開鍵だけを保存する
  • 認証時は、サーバが送った「チャレンジ」に秘密鍵で署名し、サーバが公開鍵で検証する

パスワードのように「共有の秘密」をサーバに預けないのが本質的な違いです。サーバが漏洩しても、保存されているのは公開鍵だけなので、攻撃者はなりすませません。

なぜパスワードより安全なのか

サーバ漏洩に強い

サーバが持つのは公開鍵のみ。公開鍵が漏れても、それだけでは認証できません。パスワードハッシュの流出とは状況が根本的に違います。

フィッシングに強い(これが最大の利点)

パスキーの署名はオリジン(ドメイン)に紐づきます。偽サイト acme-phishing.com でログインを促されても、認証器は「期待される RP(Relying Party)のオリジンと違う」と判断して署名を拒否します。

1. 攻撃者が偽サイト acme-phishing.com を用意
2. ユーザーが気づかず認証しようとする
3. 認証器が期待オリジン(acme.com)と照合
4. 不一致 → 署名を拒否 → 認証失敗

「うっかり偽サイトで認証してしまう」が原理的に起きにくい。パスワードや SMS ワンタイムコードでは防げないフィッシングを、仕組みで止められるのが決定的な強みです。これは TanStack/TeamPCP 事件のような認証情報窃取が横行する時代に効いてきます。

仕組み: 登録と認証の2つのセレモニー

WebAuthn の操作は「登録」と「認証」の2段階です。

登録(navigator.credentials.create)

登録(概念コード)
const credential = await navigator.credentials.create({
  publicKey: {
    challenge,                          // サーバが生成した乱数(16バイト以上)
    rp: { id: 'acme.com', name: 'ACME' },
    user: { id, name: 'jamie', displayName: 'Jamie Doe' },
    pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
  },
})
// 生成された公開鍵をサーバへ送り、検証して保存

認証器が鍵ペアを生成し、公開鍵をサーバに登録します。

認証(navigator.credentials.get)

認証(概念コード)
const credential = await navigator.credentials.get({
  publicKey: {
    challenge,                  // サーバが毎回生成する乱数
    rpId: 'acme.com',
    userVerification: 'required',
  },
})
// 署名をサーバへ送り、保存済み公開鍵で検証

認証器が秘密鍵でチャレンジに署名し、サーバが公開鍵で検証します。秘密鍵そのものは決して送られません。

認証器の種類と「同期パスキー」

種類
プラットフォーム認証器Windows Hello、Touch ID/Face ID など OS 内蔵
ローミング認証器USB/Bluetooth のセキュリティキー(YubiKey 等)
同期パスキーiCloud キーチェーン、Google パスワードマネージャ等でデバイス間同期

実用上の主役は同期パスキーです。iCloud や Google アカウントを通じて複数デバイスにパスキーが同期されるため、「機種変更したらログインできない」を避けられます。なお、パスキーは仕様上discoverable credential(保存型)である必要があり、これによりユーザー名を先に入力しなくてもログインできる(autofill UI)利点が生まれます。

管理画面に入れるときの判断材料

「自分のサービスに入れるべきか」を考えるときのチェックポイントです。

復旧手段を必ず設計する

パスキーの最大の運用課題はアカウント復旧です。デバイスを失ったときどうするか。同期パスキーである程度は緩和されますが、

  • 複数の認証器を登録できるようにする(予備デバイス・セキュリティキー)
  • メール等のバックアップ経路を用意する
  • 「全パスキーを失った場合」のサポートフローを決めておく

を設計しないと、ユーザーを締め出してしまいます。

MFA との違いを理解する

パスキーは「2要素のうちの1つ」ではなく、それ単体でフィッシング耐性のある認証になり得ます(生体認証+デバイス所持で実質多要素)。「パスワード+SMS」を「パスワード+パスキー」に足すのではなく、パスワードレスの主役として設計するのが本筋です。

段階的導入が現実的

いきなりパスワード全廃は難しいので、

  1. まず「パスキーも使える」オプションとして追加(パスワードと併存)
  2. autofill UI(autocomplete="username webauthn")で自然に促す
  3. 普及を見て、パスワードレスを既定にしていく

という段階導入が現実的です。

WARNING

WebAuthn はセキュアコンテキスト(HTTPS)必須です。また RP ID(ドメイン)の設計を最初に誤ると後で移行が大変になります。サブドメイン構成やドメイン変更の可能性を踏まえて RP ID を決めてください。

まとめ

  • パスキーは公開鍵暗号でパスワードを置き換える方式。秘密鍵はデバイスから出ず、サーバは公開鍵のみ保持
  • 最大の強みはフィッシング耐性。署名がオリジンに紐づくため、偽サイトでは認証器が署名を拒否する
  • 操作は登録(navigator.credentials.create)と認証(navigator.credentials.get)の2セレモニー
  • 実用の主役は同期パスキー(iCloud/Google 同期)。仕様上 discoverable credential が必要
  • 導入判断の肝は「復旧手段の設計」と「MFAの足し算ではなくパスワードレスの主役として設計」
  • HTTPS 必須、RP ID(ドメイン)設計は最初に慎重に

パスワードの諸問題を、運用でなく仕組みで解決できるのがパスキーの価値です。まずは「パスキーも使える」オプションとして管理画面に足すところから、段階的に始めるのがおすすめです。

参考リンク