ssh の公開鍵認証方式で YubiKey を使うための準備

## ことの発端

ここ数年で「パスワードのみの認証」は無くなり、２要素認証、多要素認証が主流になることは間違いないです。
そんな中、 USB デバイスを使用した認証モジュールが出現してきて、中でも ```Yubico``` 社の ```YubiKey``` は有名だったりします。
一般的には ```FIDO2（WebAuthn）``` で、この ```YubiKey``` を認証方法として登録したりするのですが、今回は ```GitHub``` や ```BitBucket``` などの ssh の公開鍵認証方式で ```YubiKey``` を使うことになりました。
なお、 公開鍵認証方式で ```YubiKey``` を使用するためには  ```YubiKey``` シーリーズの中でも ```YubiKey 5 シリーズ``` のように、PIV （Personal Identification Verification）という ICカード 機能を搭載しているものを使用する必要があります。

この記事では ```YubiKey 5 シリーズ``` の設定を行い、公開鍵を取得するまでをまとめています。
取得した公開鍵を使って、 ```GitHub``` を使用する手順については別の記事とさせていただきます。


## 作業の流れ

一度、流れが分かれば、そんなに手数が多いわけではないので、簡単だと思いますが、画面キャプチャが多くて見通しが悪いので、やることを下記にまとめます。

[1. インストールと起動](#1-インストールと起動)
[2. PIN を設定](#2-pin-を設定)
[3. PUK を設定](#3-puk-を設定)
[4. Managemenet Key を設定](#4-managemenet-key-を設定)
[5. 証明書を登録](#5-証明書を登録)
[6. 公開鍵を取得](#6-公開鍵を取得)


## 1. インストールと起動

YubiKey の各種設定は  ```YubiKey Manager``` を使用すると簡単です。

1. 下記 URL より ```YubiKey Manager``` をインストールします。
https://www.yubico.com/support/download/yubikey-manager/

1. ```YubiKey Manager``` を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/f15489fc-b8d6-9e8b-94e1-018176393c99.png)

1. YubiKey を挿入すると下記のような画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/ce1b33d9-66f2-364d-79e0-b68c536ce416.png)


## 2. PIN を設定

YubiKey の PIN を指定します。
この PIN は PIV のみならず FIDO2 などでも使用します。

1. ```Applications``` をクリックして ```PIV``` を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/790305b4-15ac-b8bc-fd6a-34cea58a1479.png)


1. ```Configure PINs``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/5ea6088b-09cb-dba2-d94b-ef22375803a2.png)


1. ```Change PIN``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/50662486-8c85-5aa9-a0ab-a4cd676a9f55.png)

1. ```Current PIN``` （初回設定時 [^1] は ```User default``` にチェックを入れます）、 ```New PIN``` 、 ```Confirm new PIN``` を入力して ```Change PIN``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/3633e8e0-7273-8b89-e89a-5d5d6f88f48b.png)


## 3. PUK を設定

PUK は ```PINロック解除キー（​PIN Unlock Key）``` と呼ばれるもので、 PIN を３回連続失敗してロックした YubiKey を復旧するための文字列を設定します。

1. ```Applications``` をクリックして ```PIV``` を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/790305b4-15ac-b8bc-fd6a-34cea58a1479.png)


1. ```Configure PINs``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/5ea6088b-09cb-dba2-d94b-ef22375803a2.png)


1. ```Change PUK``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/23b2a3aa-af83-27e2-c327-37a00fa38dd2.png)

1. ```Current PUK``` （初回設定時 [^2] は ```User default``` にチェックを入れます）、 ```New PUK``` 、 ```Confirm new PUK``` を入力して ```Change PUK``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/1df780bb-ee59-aa35-514e-47562523731b.png)


## 4. Managemenet Key を設定

**個人で使用する分には、この設定は行わずにデフォルトを使用した方が無難です。「何となく設定したい」レベルなら設定しないことをオススメします。**

```Managemenet Key``` を変更した後、この ```Managemenet Key``` を忘れたなんて事になると、もう証明書の追加・変更・削除ができなくなります。 [^3]
設定するケースとしては、企業内のセキュリティ担当者が証明書を登録し、むやみに証明書を変更したり削除したりしないようにする場合です。
（仮に紛失や盗難に遭ったとしても、最終的には ```PIN``` で保護されます）
ウチの会社みたいに ```YubiKey``` を社員に配布して、「勝手に設定して使ってね」というケースでは、デフォルトのままで使うことをルールとしています。

1. ```Applications``` をクリックして `PIV` を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/790305b4-15ac-b8bc-fd6a-34cea58a1479.png)

1. ```Configure PINs``` をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/5ea6088b-09cb-dba2-d94b-ef22375803a2.png)

1. ```Change Management Key``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/e13c68ce-b9d8-6a84-77f0-6f8fad679537.png)

1. ```Current Management Key``` （初回設定時 [^4] は ```User default``` にチェックを入れます）、  ```Generate``` をクリックしたら ```New Management Key``` をメモしておきましょう。 その後、 ```Protect with PIN``` にチェックを入れて ```Finish``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/e2600149-ed7e-235c-deba-e5bc9b29a4b0.png)


## 5. 証明書を登録

YubiKey には証明書を４つ保存することができますが、今回は ```Authentication（Slot 9a）``` に証明書を登録します。
ちなみに、他のスロットでも問題ないのですが、  ```Authentication（Slot 9a）``` と ```Key Management（Slot 9d）``` は１回　```PIN``` 入力を実施すると ```YubiKey``` を抜去（切断）するまで使用できます。

1. ```Applications``` をクリックして ```PIV``` を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/790305b4-15ac-b8bc-fd6a-34cea58a1479.png)

1. ```Configure Certificates``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/8a323d5a-f675-94a1-de3a-b42c4301e93f.png)

1. ```Authentication``` を選択して、 ```Generate``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/0ef4297b-aead-adfa-5c37-f853c96548b0.png)

1. ```Self-signed certificate``` を選択して、 ```Next``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/7a65f355-b290-7280-35e7-e689af2a4012.png)

1. ```Algorithm``` は ```RSA2048``` を選択して [^5] 、 ```Next``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/591ca346-5e1d-6e1b-2547-253a2da1e9b4.png)

1. ```Subject``` に 適当な名前を入力して、 ```Next``` をクリックします。（ ```Subject``` の文字列中に、このスロットの用途やスロット名 ```Authentication (Slot 9a)``` などを示した方が、後々の選択画面で迷わないのでオススメします。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/f9f018ee-59df-dba4-4eb2-00436c0a2d38.png)

1. ```Expiration data``` を入力して、 ```Next``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/79915299-843e-af86-0b1d-9dfa06a93251.png)

1. 確認画面が表示されるので ```Generate``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/aeba33ba-12cc-60f2-e329-bd1e9f799fcd.png)

1. ```Management key``` 入力して ```OK``` をクリックします。（出荷時から変更していなければ ```User default``` にチェックを入れます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/e7fba94d-9f9e-a923-b7b7-3349807d7387.png)

1. ```PIN``` を入力して、 ```OK``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/debf8b54-a98b-c92e-bfcd-53ced2e61131.png)

1. 暫くして下記のような画面が表示されれば終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/a7863cd9-af77-1b28-5165-fedd7441c31c.png)


## 6. 公開鍵を取得

一度、 YubiKey に入れた秘密鍵は二度と外に出すことはできません。秘密鍵を用いた暗号化・複合化は YubiKey 内部で実行されるため、秘密鍵が外に出ることがなく、これにより安全性を担保しています。
従って、この節でのエクスポートは公開鍵のエクスポートになります。
エクスポートした公開鍵を、各種サービスに登録することで認証サービスを使用できるようになります。

1. ```Applications``` をクリックして ```PIV``` を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/790305b4-15ac-b8bc-fd6a-34cea58a1479.png)


1. ```Configure Certificates``` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/8a323d5a-f675-94a1-de3a-b42c4301e93f.png)

1. これで証明書の作成は完了したので、 ```Export``` をクリックして公開鍵をエクスポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/b44eebda-464b-9448-7405-701be1900db8.png)

1. エクスポートされるファイルは CRT形式なので、必要に応じて下記コマンドにて ssh の公開鍵に変換します。（例として、エクスポート時のファイル名称を ```yubikey_9a.crt``` とし、 ```yubikey_9a.pub``` が変換後のファイルになります。）

```sh
openssl x509 -in yubikey_9a.crt -pubkey -noout > yubikey_9a.pub.tmp
ssh-keygen -f yubikey_9a.pub.tmp -i -m PKCS8 > yubikey_9a.pub
```


[^1]: 出荷時の ```Current PIN``` は ```123456``` です。
[^2]: 出荷時の ```Current PUK``` は ```12345678``` です。
[^3]: 出荷時の ```Management Key``` は ```010203040506070801020304050607080102030405060708``` です。
[^4]: ```Reset PIV``` を使用して、すべてを消去し出荷時設定に戻すことは可能です。
[^5]: ```ECC``` （楕円曲線暗号）をサポートしていないケースが稀にあるので、今回は ```RSA``` を設定しましたが、対向システムや運用ポリシーに応じて選択すれば良いと思います。