🗝️

YubiKeyのOpenPGP機能でリモートホストにSSHログインするまで

2021/07/26に公開

2021年7月現在。
MacOS, YubiKey 5Cで確認。

流れ

  1. 必要なソフトのインストール
  2. 楕円暗号(ed25519)を使うように設定
  3. キーの生成
  4. gpg-agentの設定
  5. PINをデフォルトから変更
  6. SSH公開鍵を表示してリモートホストに追加

1. 必要なソフトのインストール

インストールするものは以下の通り。

  • GPGTools
    • Homebrew等でgpgをインストール済みの場合は事前にアンインストールしておく
    • 後述の通りインストール対象からGPG Mailを外しておくとよい
  • YubiKey Manager CLI
    • Homebrewなら brew install ykman で入る
    • なくてもSSHログインまではできるが、あった方が便利

GPGToolsを入れるときはカスタマイズでGPG Mailをインストールしない

GPG Mail機能は有償機能なので、使わないのであればインストール時にチェックを外しておく。

インストール画面

2. 楕円暗号(ed25519)を使うように設定

gpg --card-edit でメニューに入って、 admin で管理者モードに切り替えた後、 key-attr で変更する。

$ gpg --card-edit

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: 00000000000000000000000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 00000000
Name of cardholder: [未設定]
Language prefs ...: [未設定]
Salutation .......: 
URL of public key : [未設定]
Login data .......: [未設定]
Signature PIN ....: 強制なし
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> admin
管理者コマンドが許可されています
gpg/card> key-attr
こちらのカード鍵の属性を変更します: 署名鍵
ご希望の鍵の種類を選択してください:
   (1) RSA
   (2) ECC
あなたの選択は? 2
ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (4) NIST P-384
あなたの選択は? 1
カードは、今、こちらのタイプの鍵を生成するように再コンフィグされます: ed25519
(PINを入力)
注意: カードが要求された鍵長をサポートしているという保証はありません。
      鍵生成が成功しない場合、あなたのカードに関する技術文書を確認し、
      利用できる鍵長について確認ください。
こちらのカード鍵の属性を変更します: 暗号化鍵
ご希望の鍵の種類を選択してください:
   (1) RSA
   (2) ECC
あなたの選択は? 2
ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (4) NIST P-384
あなたの選択は? 1
カードは、今、こちらのタイプの鍵を生成するように再コンフィグされます: cv25519
(PINを入力)
こちらのカード鍵の属性を変更します: 認証鍵
ご希望の鍵の種類を選択してください:
   (1) RSA
   (2) ECC
あなたの選択は? 2
ご希望の楕円曲線を選択してください:
   (1) Curve 25519
   (4) NIST P-384
あなたの選択は? 1
カードは、今、こちらのタイプの鍵を生成するように再コンフィグされます: ed25519
(PINを入力)

gpg/card> list

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: 00000000000000000000000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 00000000
Name of cardholder: [未設定]
Language prefs ...: [未設定]
Salutation .......: 
URL of public key : [未設定]
Login data .......: [未設定]
Signature PIN ....: 強制なし
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

3. キーの生成

以下の手順では、秘密鍵をYubiKeyのほかバックアップファイル (~/.gnupg/sk_xxxx.gpg) にも保存しています。バックアップファイルはオフラインメディアにコピーする等したら、安全のため削除しておきましょう。

このバックアップファイルは "This is a shim backup of the private key, not a full backup, and cannot be used to restore to a new YubiKey." ということなので、これを使って全く同じ内容のYubiKeyを作るのは無理なようです。
参考: Using Your YubiKey with OpenPGP

$ gpg --card-edit

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: 00000000000000000000000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 00000000
Name of cardholder: [未設定]
Language prefs ...: [未設定]
Salutation .......: 
URL of public key : [未設定]
Login data .......: [未設定]
Signature PIN ....: 強制なし
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 5 0 5
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> admin
管理者コマンドが許可されています

gpg/card> generate
暗号化鍵のカード外バックアップを作成しますか? (Y/n) y

工場設定のPINは下記のとおり
   PIN = '123456'     管理者PIN = '12345678'
次のコマンドを使って変更すべきです --change-pin

(PINを入力)

鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)
鍵は無期限です
これで正しいですか? (y/N) y

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: Hideo Matsumoto
電子メール・アドレス: aaa@gmail.com
コメント: 
次のユーザIDを選択しました:
    "Hideo Matsumoto <aaa@gmail.com>"

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? o
(Admin PINを入力)
(PINを入力)
(Keyのパスフレーズを入力)
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
gpg: 注意: カード鍵のバックアップが'/Users/pekeq/.gnupg/sk_AE3B7B2E9C4DA650.gpg'へ保存されます
gpg: /Users/pekeq/.gnupg/trustdb.gpg: 信用データベースができました
gpg: 鍵56FA46D6CDF41DD9を究極的に信用するよう記録しました
gpg: ディレクトリ'/Users/pekeq/.gnupg/openpgp-revocs.d'が作成されました
gpg: 失効証明書を '/Users/pekeq/.gnupg/openpgp-revocs.d/4FCB1E1B5159B15DB8C6515356FA46D6CDF41DD9.rev' に保管しました。
公開鍵と秘密鍵を作成し、署名しました。

gpg/card> list

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: 00000000000000000000000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 00000000
Name of cardholder: [未設定]
Language prefs ...: [未設定]
Salutation .......: 
URL of public key : [未設定]
Login data .......: [未設定]
Signature PIN ....: 強制なし
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 5 0 5
Signature counter : 4
KDF setting ......: off
Signature key ....: 4FCB 1E1B 5159 B15D B8C6  5153 56FA 46D6 CDF4 1DD9
      created ....: 2021-07-26 12:18:04
Encryption key....: FEF1 CBEF 8C7B 7D6E 5D03  CEEE AE3B 7B2E 9C4D A650
      created ....: 2021-07-26 12:18:04
Authentication key: 250E 3ED6 DBD2 199A FCED  E9B7 7756 2B3C 6540 2756
      created ....: 2021-07-26 12:18:04
General key info..: 
pub  ed25519/56FA46D6CDF41DD9 2021-07-26 Hideo Matsumoto <aaa@gmail.com>
sec>  ed25519/56FA46D6CDF41DD9  作成: 2021-07-26  有効期限: 無期限    
                                カード番号: 0006 00000000
ssb>  ed25519/77562B3C65402756  作成: 2021-07-26  有効期限: 無期限    
                                カード番号: 0006 00000000
ssb>  cv25519/AE3B7B2E9C4DA650  作成: 2021-07-26  有効期限: 無期限    
                                カード番号: 0006 00000000

4. gpg-agentの設定

$ vi ~/.gnupg/gpg-agent.conf
$ vi ~/.bash_profile

~/.bash_profile を編集したら一旦ターミナルを閉じて開き直す。

gpg-agent.conf
pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac
enable-ssh-support
.bash_profile
export GPG_TTY=$(tty)
gpgconf --launch gpg-agent
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)

5. PINを変更

$ gpg --change-pin
gpg: OpenPGPカードno. 00000000000000000000000000000000を検出

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

あなたの選択は? 1
PIN changed.
(古いPINを入力)
(新しいPINを入力)

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

あなたの選択は? q

6. SSH公開鍵を表示してリモートホストに追加

YubiKeyを差し込んだ状態で ssh-add -L を実行する。表示された内容をログインしたいホストの ~/.ssh/authorized_keys に追加する。

$ ssh-add -L
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINttNOgYMUfCU/yKL28fyuPHlRYMzZX9YjviTqo4gM8P cardno:000600000000

sshでログインする際は、USBにYubiKeyを挿して、ログイン時にPINを入力すればログインできる。

その他の情報

初心者(=私)がやりがちな(=やった)ミス・誤解

  • YubiKeyのPIV機能とOpenPGP機能は別物
    • PIV機能で設定したPINは、OpenPGPのPINとは全く関係ない

「以下のシリアル番号のカードを挿入してください」と表示されてPINが入力できない場合

SSHでログインする際などに、「以下のシリアル番号のカードを挿入してください」と繰り返し表示され、YubiKeyを抜き差しする等しても次に進めない場合、 ~/.gnupg/private-keys-v1.d を削除すると正常に動作するようになる。

gpg2: How to get rid of “Please insert card with serial number”, getting the same key from a different card / Yubikey

YubiKeyのOpenPGP関連情報を表示

gpg --card-status でYubiKeyに設定された内容が表示できる。

$ gpg --card-status
Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: 00000000000000000000000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 00000000
Name of cardholder: [未設定]
Language prefs ...: [未設定]
Salutation .......: 
URL of public key : [未設定]
Login data .......: [未設定]
Signature PIN ....: 強制なし
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

PINの試行可能回数を設定する

ykman openpgp access set-retries でPINの試行可能回数を設定できる。
引数には PIN-RETRIES RESET-CODE-RETRIES ADMIN-PIN-RETRIES の順で3つの数字を指定する。
設定しても gpg --card-status でRESET CODEのリトライ回数が0のままなのはよくわからない。

$ ykman openpgp access set-retries 5 5 5
Enter Admin PIN: (Admin PINを入力)
Set PIN retry counters to: 5 5 5? [y/N]: y
$ gpg --card-status | grep 'PIN retry'
PIN retry counter : 5 0 5

OpenPGP関連のデータを完全消去する

ゼロからやり直したい場合などは、 ykman openpgp reset でデータをリセットできる。ほんとうに全てが消えるので注意する。
gpg --card-edit から adminfactory-reset でも、ほぼ同じことができると思う。

$ ykman openpgp reset
WARNING! This will delete all stored OpenPGP keys and data and restore factory settings? [y/N]: y
Resetting OpenPGP data, don't remove the YubiKey...
Success! All data has been cleared and default PINs are set.
PIN:         123456
Reset code:  NOT SET
Admin PIN:   12345678

参考リンク

GitHubで編集を提案

Discussion