エンドユーザ視線からの WebAuthn 

### はじめに
WebAuthn の概要と技術的な説明は Web でたくさん見つけることができます。しかし、実際に利用することになるエンドユーザ に対して使い方を説明する資料はあまり見つかりません。ここではエンドユーザ視点で FIDO2 を使いこなすためのポイントを記載したいと思います。

WebAuth は標準化されています。独自仕様ではないため、ぬけ穴の無い、セキュアーな手続きで認証されると考えて構わないと思います。

### 認証方法
WebAuthnでは、本人確認にパスワードを使いません。ユーザ側の秘密鍵で署名したデータを Webサイト側に登録した公開鍵で検証します。これは秘密鍵で署名したデータは、秘密鍵とペアーの公開鍵でなければ検証（復号化）できないという性質を利用しています。それで本当に本人確認ができるのか、という疑問を抱く人がいるかもしれません。

### 秘密鍵 == 本人
疑問は当然かもしれません。秘密鍵の複製を他人が使う可能性があれば、本人ではなく秘密鍵の検証にすぎません。本人と秘密鍵が常に一緒でなければならないのです。秘密鍵が本人なのです。他人の秘密鍵を取得できたら、その他人に成りすますことができます。ということは、秘密鍵をどのように本人とセキュアーに結びつけているのかを把握することが、WebAuthn ( 署名を利用した認証全般　）を利用するに当たって最重要点になります。

### 秘密鍵の保管場所 / アクセス
WebAuthn ではユーザ側の秘密鍵は、OSアカント内部、セキュリティキー、クラウドに保管されます。対応する公開鍵は、Webサイト側に登録されます。
<br/>
<dl>
  <dt>OSアカント</dt>
  <dd>  秘密鍵は OS が生成。OSのユーザアカント内に保管され、外部にでることはありません。保管された秘密鍵を利用するには、鍵を保存したアカウントへアクセスするための認証が必要です</dd>
<br/>
  <dt>セキュリティキー</dt>
  <dd>秘密鍵はキー内部で生成され、キー内部に保管されます。外部にでることはありません。秘密鍵にアクセスするには PIN が必要です</dd>
<br>
  <dt>クラウド</dt>
  <dd>秘密鍵はスマホ/タブレット/PC が生成してクラウドに保存。秘密鍵を利用するには、鍵を保存したクラウドアカウントへアクセスするための認証が必要です</dd> 
</dl>
<br/>
保管された秘密鍵にアクセスするためには認証が必要です。ここでパスワード認証を求められたらパスワード不要な認証は成立しません。生体認証を有効にしておきましょう。なお、PIN 認証は生体認証に置き換えることができません。

ブラウザー/コンピュータに保存した秘密鍵がリモートから取得されるということが起きてから、秘密鍵は外部セキュリティキーに保存しなければならないと決めたケースがあります。コンピュータから取り外せるキーであれば、その内容にリモートから攻撃できません。

### 秘密鍵の利用範囲

秘密鍵がどこに保存されるかによって、鍵の扱いと利用範囲が決まります。
                    <ul>
                        <li>OSアカント: 鍵を保存したコンピュータのユーザアカントからのみアクセスできます。Webサイトには、そのコンピュータからのみログインできます。秘密鍵を他のコンピュータに移すことできません</li>
                        <li>セキュリティキー: キーを接続したり、通信可能なコンピュータ/スマホ/タブレットからアクセス（ Webサイトにログイン ）できます。キーを紛失すると秘密鍵は失われます。</li>
                        <li>クラウド: 秘密鍵を保存したクラウドアカウントにアクセスできるコンピュータ/スマホ/タブレットでアクセス（ Webサイトにログイン ）できます。秘密鍵を生成したデバイスを紛失しても別デバイスでログイン可能です</li>
                    </ul>

### 外部デバイス接続について

ユーザ側ではブラウザを実行しているコンピュータとは別の外部機器（セキュリティキー、モバイル）を使えます。それらのデバイスはブラウザを実行しているコンピュータと接続しなければなりません。

セキュリティキーは USBポートに直接接続したり、NFC(無線）接続します。スマホ/タブレットはBluetooth(無線) 接続する必要があります。

ブラウザを実行しているコンピュータ側では USBポート / NFC / Bluetooth が有効になっていなければなりません.

ここで注目すべき点は、外部機器と通信するのはブラウザだということです。ブラウザ自身に機器をやり取りする機能が組み込まれているのです。Webページはブラウザを実行しているコンピュータのハード、ファイルにはアクセスできないというのが定説でした。今でも　Webページは直接ハード、ファイルにアクセスできませんが、ブラウザー自身が公開する API を呼び出すことで、ブラウザがハードにアクセスします。


### 登録の実際

では実際に使ってみましょう。Google やヤフーのアカウントで使い始める前に、デモサイトでどのような手続きが必要になるか試すことをお勧めします。

検索するといろいろでてきます。例えば以下サイトで既定設定のまま [Register] ボタンをクリックすると登録が始まります。

https://demo.quado.io/

以下 Windows での表示例：

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/ba8ed24d-cb1d-f7fb-b1fd-0b2e561b6571.png" width="60%" >

+ 顔、PIN 
     "このデバイスにパスキーを保存”となっていますので、お使いのコンピュータに秘密鍵は保存されます。顔、PINで秘密鍵を保存するアカウントにログインできることを確認します。
     <br/>
+ 別のデバイスを使用する
　   外部デバイス（セキュリティキー、モバイル）に秘密鍵を保存するにはこちらを選択
    <br/>

**【"顔" 選択後】**
秘密鍵がコンピュータ側で生成、保存され、[OK] を押すと公開鍵は Webサイト側に保存されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/b5e4bf74-03e0-7622-3234-029b56ad2295.png" width="60%" >

上のデモサイトでは登録完了後、"4 Authenticate Your Credential" で認証テストが行えます。

**【"別のデバイスを使用する" 選択後】**
モバイルデバイスかセキュリティキーどちらで秘密鍵を生成するか選択するウィンドウが表示

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/5d77c542-65af-a87f-1283-569fdf5d540a.png" width="60%" >

**【"セキュリティキー" 選択後】**
確認ウィンドウ表示
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/9f4d35ea-f506-3854-e259-b12bf65c4e40.png" width="60%" >

(他の確認ウィンドウが表示されることがあります。[OK]で続行)

キーに PIN が未設定されていなければ PIN 設定ウィンドウが表示
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/54168b09-d6ae-e577-530b-375eb2ce8686.png" width="60%" >

PIN が設定済であれば PIN 入力ウィンドウ表示
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/3c11f395-8320-1b1e-cc14-ddd57ada1319.png" width="60%" >

キーのタッチを求められます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/b9fa5518-4270-1ebd-aa93-c2a85d60b4c0.png" width="60%" >

秘密鍵がキー内部で生成、保存され、[OK] を押すと公開鍵は Webサイト側に保存されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/87ac0bcc-f076-1f98-d89c-854fbcbd71ef.png" width="60%" >

キーを別コンピュータに接続、iPhoneに NFC接続すると、登録したWebサイトにログインできます。公開鍵は Webサイト側に保存されなければなりません。デモサイトでは保存されないため、同一ページでのみ認証テストが行えます

上のデモサイトでは登録完了後、"4 Authenticate Your Credential" で認証テストが行えます。


**【"iPhone, iPad, または Androidデバイス" 選択後】**

バーコードが表示。モバイルデバイスでスキャンします
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/4d71cf5f-f98c-28d2-e002-b5f3daf71174.png" width="60%" >

スキャン完了するとモバイルとコンピュータはBluetooth接続、モバイル側で（生体）認証します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/eae68ac8-3e64-73dc-864c-cd4c64ab3535.png" width="60%" >

秘密鍵が生成され、クラウドに保存、[OK] を押すと公開鍵は Webサイト側に保存されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/97738300-ba41-437e-7e09-55fdeaac257c.png" width="60%" >

iPhone/iPad では秘密鍵は iCloud に保存されます。Macのアカントが同じ iCloud アカウントに紐づけられていれば、Macでも TouchID で登録Webサイトにログインできます。

#### Mac の場合 ####

登録を開始すると既定で Touch ID でアカウントにログインでいることを確認。"iCloudキーチェーンに保存" という記載に注目。コンピュータに保存されずクラウドに保存されます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/c8f1910c-5bba-9627-5040-b7b935a19f7d.png" width="60%" >

"その他のオプション" を選択　（外部デバイスを利用する場合）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/6a849066-f48c-c6b1-7064-88d14427c999.png" width="60%" >

Windowsと同じように "iPhone,iPad,または Androidデバイス", "セキュリティキー”を選択して登録できます。Apple製品では登録過程でキータッチを２度求められます。画面の指示に従って進めてください。

#### iPhone / iPad　で登録 ####

モバイルでも秘密鍵はクラウドやセキュリティキーに問題なく保管され、Webサイトに公開鍵は登録されます。画面の指示に従って進めてください。


### 秘密鍵の削除 ###

iCloud に保存した秘密鍵は、パスワードアプリで個別に削除できます。セキュリティキーに保存した秘密鍵は、Windowsの機能（ 設定 - アカント - サインインオプション　- セキュリティキー - 管理 ) でリセットするとすべてを削除できます。

Webサイト側で公開鍵登録を削除すると、対応する秘密鍵ではログインできなくなります。


### まとめ ###

WebAuthnに関する Webページの多くは WebAuthnを実装する開発者向けです。WebAuthnを利用するユーザは navigator.credentials.get/create API の呼び出しに必要な引数の生成や戻り値の扱いには興味はないはずです。どのようなことに注意したら使えるのかを知りたいはずです。その答えは、秘密鍵をどこに保管するのかを意識することだと思います。そこさえ理解できれば、実際の登録作業は画面の表示される指示に従うだけで完了するはずです。

この秘密鍵がどこに保管されるのかは、実は WebAuthn を実装する開発者にとっては、あまり関係ないことです( platform / cross-platform 指定で外部デバイス、OS内部のどちらに保存かは制限できるが　）。navigator.credentials.create / get API を正しく呼びしさえすれば、以降はブラウザ側が処理してくれるので、まったく気にする必要はありません。

しかし、ユーザにとっては一番重要なことです。クラウドに秘密鍵が保存される場合、ブラウザの先のモバイル機器側の処理になります。アップル製品であれば iCloud とパスワードアプリに委ねることになります。セキュリティキーを使う場合は、ユーザ自身で管理できます。

背後にどのような処理がされていたとしても、基本は秘密鍵による署名、公開鍵による検証です。秘密鍵の保管場所と扱いがユーザ視点から WebAuthnだと思います。