パスキーが良く分からなくて迷子になっている人のためのガイド

# はじめに
最近ブラウザが「パスキーを設定しますか？」と聞いてきたりしませんか？また、巷でも「パスキーが便利！」とか「フィッシング耐性が高い！」などともてはやされている雰囲気を横目に「今はパスワードと２段階認証で十分だから、あとでしっかり読む」みたいにして先延ばしにしてませんか（はい、私が今年ずっとその状態でした）。
FIDOという言葉も数年前から耳にしていたり、Googleが専用チップを搭載したUSBデバイスを売り出したり、Microsoftに至っては「パスワードを削除する」ことを推奨したりしていますが、ブラウザサポートなどでベンダー側もいよいよ実装が仕様に追い付いてきました。
また、生成AIのせいで（おかげで）フィッシング詐欺もどんどんと巧妙化していて、従来のパスワードや弱い多要素認証などでは被害を食い止めるには不十分だという認識も共有されています。
技術者として、また一般ユーザーとして、オンラインセキュリティ向上のためにパスキーを理解することは避けて通れなくなったと感じます。
本記事が「パスキー」という言葉を耳にしたことはあるが少し迷子になっている方の助けになればと願います。

# パスキーって何？
世の中には、パスワード、パスコード、PIN、キーチェーンなど似たような言葉と概念があふれていて、そこにきて「パスキー」と呼ばれるものが登場してもうなにがなんだか分からないと思っている人もいるでしょう。
「パスキー(Passkey)」は、パスワードの代りになるような「もっと便利で安全な仕組みを作る」という目的で集まった有志の団体（FIDO Alliance)が、その仕組みを一般の人達にも分かりやすいように「Passkey」と呼ぶことにしたものです。
本記事ではこの「もっと便利で安全な仕組み」である「パスキー」を読み解いていきます。

# FIDO2のおおよその全体像におけるパスキーの位置関係

以下の図は、パスキーがFIDO2（後述）の中でどのような立ち位置にあるかを示しています。パッと見た段階では圧倒されて本当に迷子になってしまうかもしれませんが、本記事では、この全体像を地図に見立てて、パスキーの種類や目的などを分類しながら理解を深めていけるように解説したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/1bd3e011-f4d9-7b92-013c-82c3a56df2ac.png)


本記事の流れとしては上の図の「左から右」に、抽象から具体に向かって読み進めます。右端には具体的な名称が書いてあるのでピンとくるかもしれません。それらのいずれかを「自分のパスキー戦略」として採用することになるでしょうが、それ以外のパスキーの使いかをしっかり理解することで、自信をもってパスキーを使ったり、知り合いにレコメンド出来るようになるでしょう。

# FIDO2って何？
FIDO2は「公開鍵基盤を使用したパスワードレスの世界実現のための仕組み」のことです。

全体像のうちFIDO2の構成がわかる部分をズームアップして見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/61e3a322-9c3b-0770-4c56-85ce78328b84.png)

FIDO2そのものは２つの仕様から成り立っています。

* WebAuthen： ブラウザやアプリがFIDO認証を利用できるようにするJavaScriptのAPI
* CTAP（Client to Authenticator Protocol)：FIDO認証で必要になる認証器（Authenticator）というデバイスと通信するためのプロトコル

CTAPについては、私自身詳しくないし抽象的に扱えるので、この記事では省略しますが、以下の図を頭に入れておけば十分でしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/f8431464-5878-4354-c47f-8154fc34aea0.png)

本記事ではWebAuthnを辿ってパスキーの理解を進めますが、まずはFIDO2の認証の仕組みをざっくりとおさらいしておきましょう。

# FIDO2の認証の流れ

下図はFIDO2のサインインの流れをおおまかに表しています。パスキーはユーザ体験を単純化するのが目的なので、以下のような流れを知らずとも活用は出来ますが、技術者目線で納得したい方は目を通すとよいでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/bb30025c-f941-f182-2910-3a534572540a.png)


FIDO2認証には以下の３つのパーティーが参加します。

* ウェブサイト（Relying Party)：サインインしたいウェブサイトのことでFIDO2ではRelying Partyと呼ばれており「RP」などと省略することもあります
* クライアントは主にウェブブラウザのことでJavaScriptが実行環境
* 認証器（Authenticator)はFIDO2におけるもっとも機密性の高い部分で「秘密鍵」を安全に保存し、秘密鍵にアクセスするためにはさらなる認証を必要とします

ここで理解しておきたいポイント

* クライアントとウェブサイトは公開鍵暗号の仕組みに則って「チャレンジを用いたハンドシェイク」を行います
* 公開鍵・秘密鍵のペアは認証器によって生成され、秘密鍵は認証器にのみ留まり、アクセスするにはPINや生体認証などのステップが必要になります
* クライアントは資格情報を取得するステップを認証器に任せ、それをそのままウェブサイトに送り返しています
* ウェブサイトはチャレンジ、資格情報、署名などを確認してサインイン許可の判断をしています

本記事では認証の流れの深堀りはしませんが、もっと詳しく知りたい方はYouTubeで「FIDO2 authentication」で探してみてください。

# WebAuthnがマネージできる鍵には２種類ある

WebAuthnをさらに「鍵の種類」で分類します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/94a53e4b-faea-0e4e-3a65-eddba25d6df8.png)

* 発見可能キー（Discoverable key) 別名：レジデントキー、Resident key、RK: より普及が進んでいる種類のキーで「パスキー＝発見可能キー」と理解しても差し支えない
* 非発見可能キー（Non-Discoverable key) 別名：非レジデントキー、Non-Resident key、NRK: ユースケースがやや特殊でそこまで普及していない

これら２つのうち、現段階でもっとも一般的に普及していて、我々の一般的な利用シーンで意味があるのは、ひとつ目の「発見可能キー」です。２つめの「非発見キー」は技術的にとても面白い特徴を持っているので、簡単にその特徴について後述しますが無視しても差し支えありません。

## 発見可能キーとは？
「パスキー」は利便性を高めるという目的があり、利便性のひとつとして「ユーザがいちいち指定しなくても勝手に選んでくれる」という振る舞いがあります。「誰が何を発見してくれるのか？」というと「認証器が、ウェブサイト（RP)をヒントに、認証器に保存されている秘密鍵と資格情報を発見して表示してくれる」ということなのです。

発見可能キーの特徴としては

* 認証器に鍵のペアと追加の資格情報（ウェブサイトのドメインなど）を全てひとつのユニットとして保存している（このひと固まりを「パスキー」と理解してオッケー）
* この種類のパスキーは認証器のデータ領域を消費するので、保存できるパスキーには上限があります
* 資格情報メタデータの一部としてユーザ名なども保存でき、この場合パスワードどころかユーザ名すら入力しなくてよくなる（password-less + username-less を実現できる！）

私たちが普段使うパスキーはほとんどの場合発見可能キーです。

## 非発見可能キーとは？
前述したように非発見可能キーはメインストリームのユースケースではありませんが、技術的に興味深い仕様です。ただ興味がない人は飛ばしても得に一般的なパスキーを活用する上で困ることはありません。

非発見可能キーも「パスキー」と呼べますが、その最大の特徴は「秘密鍵が認証器に保存されていない」ことです。替りに「秘密鍵はサーバー側に保存されています」。これを読んで「そんなバカな」と思ってしまうのも無理はありません。ですが以下のような流れでFIDO2認証を実現できるのです。

1. 認証器が生成した公開秘密鍵ペアは認証器がハードウェアレベルで暗号化し、サーバーに送信します（このような鍵をKey Encrypting Key - KEKなどと呼びます）
1. サーバーは暗号化された暗号文（パスキー）をストレージに保存します（この分余計にサーバ側の実装が別途必要になります）
1. クライエントがサーバーにサインインを要求する際にユーザの情報をヒントとして渡します（ユーザ名など）
1. サーバーはローカルに保存されているパスキーから指定されたパスキーを選び（もしくは複数ならリスト表示し選択させる）、ひとつの暗号化された状態のパスキーをクライエントに送信します
1. クライエントは認証器に暗号化された状態のパスキーを渡します
1. 認証器は暗号化された状態のパスキーをハードウェアレベルの鍵で復号して、さらに内部にあった秘密鍵を取得します（この段階で発見可能キーが認証器に秘密鍵を保存していた状態に追いつきます）

この一連の流れで何が良いかというと「認証器のストレージを消費しない」ので「無限のパスキーをマネージできる」という利点があるのです。もちろん、サーバ側が非発見可能キーをサポートしている場合に限りますが。

非発見可能キーは発見可能キーのように「自動的にパスキーを選択してくれる」という利便性が欠けます。ただ、サーバ側に実装があれば、まずサインインに伝統的なユーザ名＋パスワードを行い、多要素認証としてパスキーを設定することが容易に可能になります。どうしてもユーザ名＋パスワードをサポートしなくてはいけないが、従来のSMSや電子メールによる多要素認証では不十分な場合などは非発見可能キーは理想的なバランスを取れるかもしれません。

# 発見可能キーを「マルチ・デバイス」と「シングル・デバイス」に分類する

より一般的に普及しつつある「発見可能キー」をさらに分解していきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/5a6ceed0-0680-c9e2-9c8d-0e0979cd2cae.png)

前述したように「発見可能キーとしてのパスキー」は認証器に丸っと保存しているので、例えば自分のスマートフォンで Amazon.com にパスキーを使ってサインインするように習慣化したい場合、一旦Amazon.comとパスキー設定を完了すれば、認証器がそのパスキーを保存するので次回からのサインインは簡単になります。

すると「そのパスキーは、スマフォ以外の別のデバイス、例えばタブレットとかノートパソコンとかでも使えるのか？」という疑問が生まれますね。

答えは「マルチデバイス対応のパスキーなら使える」です。そして、マルチデバイス対応のパスキーを使うには、パスキーを同期できるクラウドサービスと統合したアカウントでパスキーを設定する必要があります。

逆に言うと「マルチデバイス対応のパスキーではなく、シングルデバイス用のパスキーを設定した場合は、そのパスキーはそのデバイスでしか使えない」となります。

以下に整理してみましょう

* マルチ・デバイス パスキー
    * 特定のサービス（例：amazon.com)につき、クラウドと連携しているアカウント上で、パスキーを一回だけ設定する
    * パスキーは複数のデバイスに自動で同期される
    * パスキー（秘密鍵）はクラウド上に保存されるのでセキュリティはやや落ちるがその代わりに利便性が増す
    * パスキー紛失のリスクが低い（全てのデバイスが水没してもパスキーは普及できる）
* シングル・デバイス パスキー
    * 特定のサービス（例：amazon.com)と、特定のデバイスにつき、パスキーを設定する
    * そのパスキーはそのデバイスと紐づけられるので他のデバイスで同じサービス（例：amazon.com)するために使うことが出来ないので、別途パスキーを他のデバイスで設定する必要が生じる
    * パスキー（秘密鍵）はクラウドには保存されず、デバイスにのみ保存されるのでセキュリティが向上するが利便性は落ちる
    * パスキー紛失のリスクが高い（全てのデバイスが水没したらパスキー以外のサインイン手段が必要）

つまり、マルチ・デバイスのパスキーとシングル・デバイスのパスキーの唯一の違いは「どこにパスキーを保存するか」となります。

# マルチデバイス対応のパスキーを「シングル・プラットフォーム」と「マルチ・プラットフォーム」に分類する

クラウドを使ってパスキーが同期される種類のパスキーを「マルチデバイス対応パスキー」と呼びますが、ではどのクラウド（をベースにしたエコシステム）を選択すれば良いか？という疑問が生まれます。

* シングル・プラットフォーム：特定のプラットフォーム（例：Apple）が管理するクラウド上で構築されるパスキー同期の仕組み
* マルチ・プラットフォーム：特定のプラットフォームやベンダーにロックインされず、異なるプラットフォームで横断的に同期する仕組み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/7516cc62-15c0-6d89-4dc6-caef644421b6.png)

この場合「ベンダーロックインを気にしないか？」がひとつの判断基準になるでしょう。

例えばスマートフォンはiPhone、ノートパソコンはMacBook、たまに映画はiPadで見て、写真などはすべてiCloudにバックアップ、という方は迷わずApple IDで統合されたiCloud キーチェーンを選択して構わないでしょう。その場合「シングル・プラットフォーム」を選んだことになります。

同様に、Googleのサービス、Chromeブラウザ、そしてAndroidデバイスで囲まれて生活しているのなら Google Accountで統合したGoogleエコシステム上にパスキーを保存する戦略が意味を成すでしょう。

このようなシングル・プラットフォームのパスキー管理の最大の利点はその利便性です。基礎となるクラウドは特定のベンダーの管理化にあるし、デバイスやOSとも深く統合出来ると考えられるので、その分セキュリティは期待できます。

一方で「マルチ・プラットフォーム」を選択する理由としては、異なるベンダーのデバイスを所有している（スマートフォンはiPhoneでパソコンはWindowsでタブレットはAndroid）場合、プラットフォームをまたがったパスキーの同期は不可能な場合が多いです。

実際に私は上記のようなケースなので「1password」を使ってパスキーを管理しています。そうすることで、Windows PCで設定したAmazon.comに対するパスキーをWindowsにインストール済みの 1password アプリに保存するこで、iPhoneからAmazon.comにサインインしたい場合にはスマートフォンにインストール済みの（そして自動的に同期されている）1passwordから同じパスキーを指定してサインインすることが可能になります。

# シングル・デバイスのためのパスキー

前項で「マルチデバイス対応」のパスキーは、文字通り「いったん設定したら複数のデバイスで利用できる」と書きましたが「シングル・デバイス」を前提に設定したパスキーは当然それが出来ません。ただし、これをデメリットととらえるかメリットととらえるかは状況によります。






![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/9cbc4069-0eb9-33bb-4a74-e7c800227933.png)

セキュリティ面ではシングル・デバイスでのみ使えるパスキーは非常に強力です。デバイスそのものを盗まれたりすることが無いかぎり、知らないうちにパスキーが漏洩することはあり得ないので、特に高いセキュリティを要求されるようなサービス（例えば銀行などの金融系サービス）ではデバイスに紐づけられるパスキーが好ましいかもしれません。

ただ、シングル・デバイスのパスキーであっても以下のふたつの認証器の場所の違いで利用方法が変わってきます。

* デバイス本体に認証器が備わっている場合：秘密鍵を厳重に管理するために専用チップ（ハードウェア）を搭載したデバイスを利用します
* 所有するデバイス（例：スマートフォンやパソコン）に接続して使う外部デバイスとしての認証器：秘密鍵の厳重な保管場所としてUSBサムドライブのようなフォームファクターを持ったデバイスを利用できます

デバイス本体に認証器が備わっているものとしてはAppleのEnclaveやGoogleのTitan,そしてMicrosoftのWindows Hello（TPMに依存）があります。この場合、ユーザは認証器の存在を気に変えることもなく、極めて安全にパスキーをマネージできます。手持ちのデバイスにつき、それぞれのサービスに対してパスキーを設定するというやり方は初期の設定はやや煩雑ですが、セキュリティ面では最強だと言えます。このセキュリティのセットアップを突破することはほぼ不可能と言えるでしょう。

一方、外部デバイスにパスキーを保存するやり方にもいくつかメリットがあります。例えば、Yubico社のYubikeyという取り外し可能なUSBデバイスを使って各種サービスに対してパスキーを設定し、そのUSBデバイスを手持ちのスマートフォンやパソコンに接続してそこで同じパスキーを利用することが出来ます。つまり「シングル・デバイス」パスキーでありながら、実質的には複数のデバイスでパスキーを使うことが可能になるのです。

外部デバイスの中にはUSBデバイスのような物理的に接続するもの以外にもNFCやBluetooth通信を使ったワイヤレスの認証器デバイスもあります。

どちらのやり方も、紛失のリスクがありますから、バックアップ戦略が重要になります。いくつか挙げるとしたら：

* USBデバイスを複数用意し、それぞれのUSBデバイスで、各サービスに対してのパスキーを設定し、USBデバイスを物理的に離れた場所に保管する（ひとつは持ちあるいて普段使い、残りのひとつはバックアップ）
* それぞれのサービスに従来型のパスワードでのサインインオプションを保持しておく（パスワードは強力なものにしてパスワードマネージャなどに保存しておく）

# パスキーの最大のメリット：フィッシング詐欺対策

FIDO2のゴールには「煩雑で危険なパスワードからの開放」がありますが、同時に「フィッシング詐欺被害を減らす」という好ましい副作用も期待できます。フィッシング詐欺の被害は広がる一方で、それでいてユーザの多くはいまだに、パスワードの使いまわし、覚えやすいパスワード、２段階認証（多要素認証）をオフにしたまま、といったアンチパターンのままです。

フィッシング詐欺対策を具体的に言うと「ユーザの入力を減らす」があります。例えば普段からパスワードを入力する作業をしないで済めば、仮にフィッシングされたとしても「パスキーを指定する」だけだとパスワードは漏洩しようがありません。これは仮に当該サービスに「バックアップのサインイン方法」としてパスワードがいまだに設定されていたとしてもです。つまり「普段のユーザの行動」としてパスワード（秘密）を入力しないようにすればよいのです。

パスキーはまさにそれを実現します。また、パスキーは「リプライ攻撃」という種類のハッキングについても耐性が強いのでセキュリティ上のメリットはさらに多くなります。
パスキーの普及はフィッシング詐欺を減らすことは間違いありません。

# おわりに

本記事ではパスキーの種類、目的、メリット・デメリットのトレードオフなどが理解できるように、FIDO2の文脈から分解しつつ解説しました。
運用にあたっては具体的な方法や制約があると思うので、いくつか試しつつメインの戦略を練っていくのが良いかと思います。

私個人に関しては、すでに「家族とのシークレットのシェア（仮に私が死んだときに私の全てのアカウントに安全にアクセスできる、という要求を満たす）」が重要であり、また「セキュリティは単純であるべき」という原則を重視し、なおかつ「ベンダーロックインは避けたい」という理由で「1passwordでパスキーを設定する」方針にしました。

それぞれの状況に合わせて、いずれかの形でパスキーを利用することをお勧めします。