YubiKey 5はPIV (Personal Identity Verification) という規格に対応しています。PIVとは米国政府機関が発行するスマートカードのことで、YubiKeyではこれを操作することができます。
YubiKey 5のPIVは、RSA 1024 / RSA 2048 / ECC P-256 / ECC P-384に対応しています。今回はYubiKey内にECC P-384の鍵を生成し、保存した鍵を利用してSSHログインできるようにしてみようと思います。
検証環境
- YubiKey 5C NFC Ver.5.2.7
- macOS Big Sur Ver.11.5.2
ツールのインストール
YubiKeyのコマンドラインツールykman
と、スマートカードを扱うためのライブラリ、ユーティリティを提供しているOpenSCをインストールします。
$ brew install ykman opensc
検証時のMacではYubiKeyに保存したECC鍵を読み込むことができませんでした。
$ ssh-keygen -D /usr/local/lib/opensc-pkcs11.so -e skipping unsupported key type failed to fetch key unknown certificate key type failed to fetch key Enter PIN for 'SSH key': skipping unsupported key type failed to fetch key unknown certificate key type failed to fetch key cannot read public key from pkcs11
これはデフォルトでインストールされているOpenSSHがLibreSSL 2.7.3でビルドされているのが原因でした。 HomebrewにあるOpenSSHはOpenSSL 1.1以上でビルドされているようなので、こちらをインストールすることで回避できます。
$ brew install openssh
Homebrewでインストールしたsshコマンドを実行できるように/usr/local/bin
をPATHの先頭に追加します。
$ export PATH=“/usr/local/bin:$PATH”
私の環境では以下の通りでした。
$ which ssh /usr/local/bin/ssh $ ssh -V OpenSSH_8.7p1, OpenSSL 1.1.1l 24 Aug 2021
鍵を生成
- 鍵ペアを生成
YubiKeyのPIVには証明書を保存するために4つのスロットがあります。 それぞれの用途は公式ドキュメントを確認してください。
今回はスロット 9a (PIV Authentication) を使用していきます。公開鍵はpubkey.pemというファイル名で出力します。
$ ykman piv keys generate -a ECCP384 9a pubkey.pem Enter a management key [blank to use default key]:
Management Keyを入力して鍵ペアの生成は完了です。
- 自己署名証明証を生成
pubkey.pemを持つ自己署名証明書をスロット 9aで生成します。
$ ykman piv certificates generate -s 'SSH key' 9a pubkey.pem Enter a management key [blank to use default key]: Enter PIN:
Management KeyとPINコードを入力して自己署名証明書の生成は完了です。
- 確認
$ ykman piv info PIV version: 5.2.7 PIN tries remaining: 3 Management key algorithm: TDES CHUID: 3019d4e739da739ced39ce739d836858210842108421c84210c3eb3410d04f85e66ea295b74b4c523c7ec9a8bf350832303330303130313e00fe00 CCC: No data available. Slot 9a: Algorithm: ECCP384 Subject DN: CN=SSH key Issuer DN: CN=SSH key Serial: 38854637746760389760709390196415882874710771519 Fingerprint: 4e7bf6cf4491a692c5f82ca56046b91f23e5210020402fa4dc5e7b0e13b3dca7 Not before: 2021-08-26 06:12:10 Not after: 2022-08-26 06:12:10
実際に保存されているPEM形式の公開鍵を取得してみます。
$ ykman piv certificates export -F PEM 9a cert.pem $ openssl x509 -in cert.pem -pubkey -noout -----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEyxDRpSughb7+Q0Yf6LOZpC3zBzl22Q5R DS41qCdA33fx5+VGkofRlUO078vd7G1vTEpF8/uiZ2IdCJxkrpVmrDE6iwMxwah1 0x4VczU0Bap3NIe1YrxbU92Tn/pnC72N -----END PUBLIC KEY-----
PEM形式の公開鍵が出力されていれば成功です。
SSHの設定
今回はローカルホストに対してSSHを試してみます。
~/.ssh
ディレクトリがなければinstall -m700 -d ~/.ssh
で作成しておいてください。
- 公開鍵を登録
ssh-keygen -D
するとSSHの公開鍵のフォーマットで出力されます。
これをローカルのauthorized_keysに保存し、公開鍵認証でログインできるようにします。
ssh-keygen -D /usr/local/lib/opensc-pkcs11.so >> ~/.ssh/authorized_keys
リモートに登録する場合は
ssh-keygen -D /usr/local/bin/opensc-pkcs11.so > /tmp/key.pub ssh-copy-id -i /tmp/key.pub
で登録するといいかと思います。
- SSHしてみる
ssh -I /usr/local/lib/opensc-pkcs11.so localhost Enter PIN for 'SSH key':
Enter PIN for 'SSH key':
でYubiKeyに登録されているPINを入力するとログインできます。
~/.ssh/config
に設定
~/.ssh/config
にPKCS11Providerを設定するとssh -I
する必要がなくなります。
Host * PKCS11Provider /usr/local/lib/opensc-pkcs11.so
まとめ
SSHの鍵をYubiKeyに入れておけば、マシーンに依存せず同じ鍵でSSHできるようになります。YubiKeyから秘密鍵を取り出すことができないので、YubiKeyさえ紛失しなければ流出の心配はないと思います。
しかし、今回YubiKeyで直接鍵を生成したのでYubiKeyの故障の際は鍵の登録し直しが必要になります。鍵がなくなると困るような場合は、ssh-keygenで生成した鍵をYubiKeyにインポートすることも可能ですので、こちらの機能を試してみるといいかもしれません。