YubiKey+Pageantでらくらく秘密鍵管理 on Windows

SSH（やSCPなどSSH上で動かすサービス）を使うには秘密鍵が必要ですが、管理は意外と面倒だったりします。今回は、Windows上で、ハードウェアトークンであるYubiKeyを、Pageantと併用することで秘密鍵管理をすっきり解決できたので、それについてまとめてみます。

# 秘密鍵管理について
## 面倒な秘密鍵管理
秘密鍵はもちろん秘密にすべきものなのですが、ソフトウェアによって必要な鍵の形式が違うとか、あとはパスフレーズの入力が面倒になって、いくつもの鍵が乱雑に転がっていることも、決して珍しいことではありません。また逆に、いざ出先でアクセスしようとなった場合にも、秘密鍵はデータになっているのうえになくすと大変という性質上、簡単に持ち運べるものでもないという不便さがあります。

原則論を言えばマシンごとに秘密鍵を用意すべきなのですが、今度は加速度的に鍵が増えていってしまいます。

## YubiKeyとは
[YubiKey](https://www.yubico.com/products/yubikey-hardware/)[^1]は、USBポートにつないで使うタイプのトークンで、モデルにもよりますが以下のような機能を備えています。

* ワンタイムパスワードの生成
* FIDO U2F（Google 2段階認証に利用可能）
* 公開鍵暗号用のスマートカード

## YubiKeyのメリット
ここで、YubiKeyに秘密鍵を入れるメリットを挙げていきます。

* コンパクトな物になっているので、持ち運びできる
* 逆に、物理的に存在しないと使えないので、管理しやすい
* 秘密鍵は**本人でさえも**取り出せないので、攻撃にも強い[^2]

## 鍵エージェントって？
SSHの鍵は安全上パスフレーズをかけることが多いですが、（特にUnix系では）SCPなど細かい単位で必要になることもあるので、都度打つのでは明らかに手間が掛かり過ぎます。ということで、SSHの鍵を一括して管理してアプリからの問い合わせに答えるような、鍵エージェントと呼ばれるツールが存在しています。

Windowsでは、PuTTYのPageantが広く使われています。

## 鍵エージェントを使うメリット・デメリット
鍵エージェントを使うことで、鍵をまとめて管理できるということはもちろんメリットです。今回の例では、Pageantさえスマートカード対応のに差し替えてしまえば、あとのソフトウェアはそのままでYubiKeyの鍵を使えるようになります。

ただし、利便性のためとはいえ（ふつうの鍵ファイルの場合）メモリ上でパスフレーズ解除しているのと同じ状態になるので、セキュリティ的には隙が生じることになります。

# 設定してみる
今回使用したソフトウェアは以下のとおりです。

* Windows 7 x64版
* [OpenSC](https://github.com/OpenSC/OpenSC/wiki) 0.15.0 32bit版
* [PuTTY-CAC](http://www.risacher.org/putty-cac/)
* [YubiKey用ツール](https://www.yubico.com/support/downloads/) PIV 1.2.1
* Pageant対応の各種ツール（TeraTerm、WinSCP、SourceTreeなど）

## YubiKey側の設定
今回は[YubiKey 4](http://yubi.co/4)を使いましたが、これは最初からPIVモードが入っています。ということで、接続してからYubiKey PIV Managerを開いてみましょう。

まずは、右側の「Manage Device PINs」で、秘密鍵を使う時のパスワードなどを設定しておきましょう（設定しないと、第三者に使われてしまうこともありえます）。

設定が済んだら、左側の「Certificates」から、いちばん左の「Autentication」を選んで「Generate new key」から鍵を生成しましょう。特に理由がなければRSA 2048ビットでいいと思います。

鍵自体はあっさり生成できますが、この秘密鍵はエクスポートできず、YubiKeyの中から取り出せなくなっています。

## サーバ側の設定
鍵はできあがりましたが、SSHで使えるようにするにはサーバ側にセットする必要があります。OpenSCを使うことで、SSH用の公開鍵を抽出できます。

```
"C:\Program Files (x86)\OpenSC Project\OpenSC\tools"\pkcs15-tool --read-ssh-key 1
```
このコマンドの後にパスフレーズを入力すると、`ssh-rsa AAA………`という公開鍵が出力されます。あとは公開鍵を目的のサーバの`~/.ssh/authorized_keys`に追記することで準備完了です。

## Pageantの設定
Pageantは通常のものではなく、Windowsのスマートカードライブラリを参照するようになっている[PuTTY-CAC](http://www.risacher.org/putty-cac/)を使います。別途のライブラリは必要なく、`pageant.exe`単体で動きますので、それだけダウンロードして、起動することでエージェントとしてタスクトレイに常駐します（よく使うならスタートアップに入れるといいでしょう）。

で、起動直後には鍵リストは空っぽになっています。pageantのタスクトレイアイコンを右クリックするとメニューが出ますが、「Add Key」**ではなく**「View Keys」からリストウィンドウを表示してください（タスクトレイの左クリックでも出ます）。

ダイアログが開くと、下の方に「Add CAPI Cert」というボタンがありますので、こちらを押すとWindowsで使用可能な証明書を探して、リストとして表示してくれます。無関係な証明書が出ることもありますが、YubiKeyのはICカードの絵になっていますので、それを選んでください（この時点ではパスフレーズを聞かれませんが、それで正常な動作です）。

## 実際に接続してみる
たとえばTeraTermでは、接続先を選んだ次に、ユーザー名やパスワードを設定するダイアログが出ますが、そのいちばん下に、「pageantを使う」という選択肢があります。これを選ぶと、pageant経由でWindowsが暗証番号の入力ダイアログを出してきます。そこでYubiKeyのPINを入力すると、YubiKey内部の鍵を使ってSSHの認証が進んでいくことになります。

## Cygwin/MSYSから使う
CygwinやMSYSの環境向けに、pageantを`ssh-agent`として使えるようにする[cuviper/ssh-pageant](https://github.com/cuviper/ssh-pageant)というものがあります。[そちらの使い方については別項にまとめてみました](http://qiita.com/jkr_2255/items/f1ebd3fa4a9bf8ee1b03)。

# 関連記事
* [秘密鍵、管理してますか? YubiKeyで鍵の一元管理とSSH接続、２段階認証の高速化を試す](http://qiita.com/dseg/items/77d77467970b1b510285)

[^1]: **Y**our **ubi**quitous **Key**の略で、日本語の「指」とは関係ありません。
[^2]: 公開鍵暗号の処理もYubiKey内部で行っているので、秘密鍵は一切外に出ません。