Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

YubikeyにPIVを入れる / Yubikey gpg-agent PIV 喧嘩しない 方法

自宅サーバの認証もろもろで遊んでみたかったので、YubikeyをPIVとして使ってみたところ、gpg-agentとpcscdが Yubikeyを取り合ってしまったので、それを直したメモ。まずPIVの証明書をYubikeyにインストールした話をして、次にgpg-agentがうまく動かないのを直した話をします。

いったんPIVを作成した話です

PIVというのは、ようするにアメリカの政府機関が使う身分証の規格で、オープンになっている。偉い。日本も見習ってほしい。

で、PIVにはX.509証明書を入れてなんやかんやできる。どういうなんやかんやができるかというと、sshができたりKerberos認証ができたりする(はず)。今回は鍵アルゴリズムをECCP256にして作成した。

YubikeyのPIV領域をいじるにはykmanを使う(大抵のディストロでyubikey-managerといった名前でパッケージされている)。

鍵作成

$ ykman piv keys generate --algorithm ECCP256 9a yubikey-piv-pubkey.pem

これで秘密鍵がYubikeyに生成され、公開鍵がyubikey-piv-pubkey.pemとして出力される。

9aと指定しているのはPIVにおけるスロット番号で、いくつかある:

  • 9aと9dは、認証に使うため(パソコンにセットするとか)に作られたため、一度PINコードを入力するとUSB接続が切れるまで使えます。
  • 9cはファイルのデジタル署名に使うため、署名するたびにPINコードが必要になります。
  • 9eは、建物の入館時のドアロックの解除などに使うため、PINコードが必要ありません。 Yubikey 5のPIVで遊ぶ ( SSH鍵生成&保管 ) - Qiita

今回は認証用途なので9aスロットを指定した。

スロットの詳しい情報は以下にまとまっている:

developers.yubico.com

自己署名

自分は認証局を運用しているわけでもないので、自己署名する:

$ ykman piv certificates generate -s 'CN=Windymelt,DC=3qe,DC=us' 9a yubikey-piv-pubkey.pem

-sオプションはSubjectで、X.509証明書とかで見るおなじみの文字列だ。3qe.usのWindymeltさんなので上掲のような表記にした。

これで自己署名ができた。状態を確認する:

$ ykman piv info
PIV version: 5.4.3
PIN tries remaining: 3/3
Management key algorithm: TDES
CHUID:  ...
CCC:    No data available.
Slot 9a:
        Algorithm:      ECCP256
        Subject DN:     CN=Windymelt,DC=3qe,DC=us
        Issuer DN:      CN=Windymelt,DC=3qe,DC=us
        Serial:         ...
        Fingerprint:    ...
        Not before:     2022-10-08 22:42:54
        Not after:      2023-10-08 22:42:54

スロット9aに証明書が格納された。

gpg-agentが動かないのを直す

PIVとして動作するようになったのはいいものの、スマートカード用のデーモンがYubikeyの制御権を奪ってしまったのか、gpg-agentでPGP鍵の様子を見られなくなってしまった:

$ gpg --card-status
gpg: selecting card failed: そのようなデバイスはありません             
gpg: OpenPGPカードが利用できません: そのようなデバイスはありません

gpgはCCIDというよりローレベルなAPIかなんかを使ってYubikeyと通信しようとしているようだ。一方で、PIVの機能はpcscdというドライバ?経由でやっているみたい。(このへんの規格が難しい)

これは困ったなーと思っていると、Arch wikiに解決策が載っていた:

wiki.archlinux.jp

gpg-agentにもpcscdを使ってもらえばよいみたい。以下のようにして解決した:

  • ~/.gnupg/scdaemon.confを作成する:
pcsc-driver /usr/lib64/libpcsclite.so
card-timeout 5
disable-ccid

libpcsclite.soの位置は環境依存なので、真似するときは自分の環境で確認してほしい。そして再起動して終わり。

$ gpg --card-status
Reader ...........: Yubico YubiKey OTP FIDO CCID 00 00
Application ID ...: ...
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: ...
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 : 16
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: B09D EBF2 07AB C1CC 6473  4120 0B06 77A6 5336 EE08
      created ....: 2022-10-02 12:41:39
Encryption key....: 65A6 08AA A076 BCE3 5B5B  C128 0D53 5FB1 7638 2021
      created ....: 2022-10-02 12:37:20
Authentication key: B09D EBF2 07AB C1CC 6473  4120 0B06 77A6 5336 EE08
      created ....: 2022-10-02 12:41:39
General key info..: sub  ed25519/0B0677A65336EE08 2022-10-02 Windymelt <windymelt@3qe.us>
sec#  ed25519/F2FC63C242C04D9D  作成: 2022-10-02  有効期限: 無期限    
ssb>  cv25519/0D535FB176382021  作成: 2022-10-02  有効期限: 2023-10-02
                                カード番号: 0006 ...
ssb>  ed25519/0B0677A65336EE08  作成: 2022-10-02  有効期限: 2023-10-02
                                カード番号: 0006 ...

よしよし

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?