
PIV対応YubiKeyでx509証明書を管理し、キーと証明書要求を生成して、gitコミットやファイルの署名・検証を行います。
Pivit は、PIV アプレット対応スマートカード (Yubikey) に保存されている x509 証明書を管理し、それらの証明書を使用してデータの署名と検証を行うためのコマンドラインツールです。
これは、git コマンドラインがコミットやタグの署名・検証のために外部プログラムを呼び出す方法と完全な互換性があります。
brew install pivit
go install github.com/cashapp/pivit/cmd/pivit@latest
pivit を使って署名と検証を行うように git を設定するには、次のコマンドを実行します:
git config --(local|global) gpg.format x509
git config --(local|global) gpg.x509.program pivit
pivit --reset
Yubikey の PIV アプレットをリセットし、アクセス用の新しい PIN を作成します。
pivit --generate [--p256] [--self-sign | --no-csr] [--assume-yes] [--pin-policy] [--touch-policy]
Yubikey のカード認証スロットに新しいキーペアを生成します。
このコマンドは、生成されたキー用に Yubico によって署名された x509 証明書も生成して保存します。
--p256 オプションを指定すると、楕円曲線 P-256 を使用してキーペアが生成されます。
それ以外の場合は、曲線 P-384 が使用されます。
自己署名証明書を生成するには、--self-sign フラグを追加します。
この証明書は、新しく生成されたキーで署名されます。
自己署名証明書が本当に必要なのかを確認するプロンプトが表示され、
その後 PIN の入力、そして Yubikey へのタッチが求められます。
出力の最後には CERTIFICATE_REQUEST の代わりに 3 つの CERTIFICATE ブロックが含まれます (出力例は後述)。
このオプションは主にテスト目的で役立ちます。
--assume-yes フラグは --self-sign オプションと組み合わせて使用でき、その y/n プロンプトを無効にします。
--no-csr フラグを追加すると、証明書署名要求 (CSR) の出力をスキップできます。この場合、Yubikey へのタッチを求められません。
このオプションは、生成したキーを既存の PKI の一部にする必要がない場合に役立ちます。
Yubico の証明書を使用して、キーの証明書を引き続き検証できます: こちら
--pin-policy フラグは、生成されたキーにアクセスする際に PIN をいつ要求するかを制御します。
never、once、always のいずれかに設定します (デフォルトは never)。
--touch-policy フラグは、生成されたキーにアクセスする際にハードウェアへの物理的なタッチをいつ要求するかを制御します。
never、cached、always のいずれかに設定します (デフォルトは always)。
このコマンドの出力は次のようになります:
Printing Yubikey device attestation certificate:
----- BEGIN CERTIFICATE -----
...
----- END CERTIFICATE -----
Printing generated key certificate:
----- BEGIN CERTIFICATE -----
...
----- END CERTIFICATE -----
Printing certificate signing request:
----- BEGIN CERTIFICATE REQUEST -----
...
----- END CERTIFICATE REQUEST-----
末尾の CERTIFICATE REQUEST は、新しく生成された秘密鍵によって署名されており、CA によって署名された証明書を発行するために使用できます。
自分で証明書を発行して使用する場合は、以下も確認することが重要です:
Pivit では、環境変数を介して CSR にさまざまな属性を設定できます。
次の証明書オプションが以下のように設定されます:
Subject.CommonName は、PIVIT_EMAIL 環境変数の値に設定されます。Subject.Organization は、PIVIT_ORG 環境変数の値に設定されます。Subject.OrganizationalUnit は、PIVIT_ORG_UNIT 環境変数の値に設定されます。さらに、次の Subject Alternative Name (SAN) が証明書要求に含まれます:
PIVIT_EMAIL が含まれますPIVIT_CERT_URIS 環境変数で指定されたすべての URL が含まれます (URI はスペースで区切られます)PIV モジュールは、キーと証明書を保存できる複数のスロットをサポートしています。
利用可能なスロット - 9a、9c、9d、9e。
9e は「カード認証」スロットです。9a は「認証」スロットです。システムログインなどの操作に使用されます。9c は「デジタル署名」スロットです。ドキュメントへの署名、またはファイルや実行ファイルへの署名に使用されます。9d は「鍵管理」スロットです。機密保持の目的で電子メールやファイルを暗号化するなどに使用されます。詳細はこちら を参照してください。
pivit では、-w フラグを使用してスロットを選択できます。
各コマンドでスロットが指定されていない場合、デフォルトで 9e が使用されます。
例:
証明書の生成
pivit --generate [-w slot]
署名
pivit -s -u userid [-w slot]
証明書の出力
pivit --print [-w slot]
デフォルトでは、pivit は 1 台の Yubikey が接続されていることを想定しています。システムに複数のカードリーダーや Yubikey がある場合、または
pivit が意図した Yubikey と通信していることを単に確認したい場合は、PIVIT_YK_SERIAL 環境変数でシリアル番号を指定します。
例:
PIVIT_YK_SERIAL=13078292 pivit --print
これは任意のコマンドで使用できます。
pivit --import [--first-pem] [file]
file から証明書をインポートします。
指定されたファイル名には、PEM ブロックとしてエンコードされたシリアル化された x509 証明書が含まれている必要があります。
この操作では Yubikey の PIN を要求されます。
--first-pem を追加すると、file から最初の PEM ブロックをインポートし、残りを無視します。これは、発行した証明書をチェーンまたはバンドルとして提供し、その先頭にエンドエンティティ証明書を配置する CA (これが慣例です) を使用する場合に役立ちます。
pivit --print
Yubikey のカード認証スロットに保存されている証明書を、そのフィンガープリントとともに出力します。
例:
> pivit --print
bad126c47dc90e90e0c7ec90ec682b1717e52757
-----BEGIN CERTIFICATE-----
MIICczCCAVugAwIBAgIRANATKTxzlHOJgMdV30XRz5kwDQYJKoZIhvcNAQELBQAw
ITEfMB0GA1UEAwwWWXViaWNvIFBJViBBdHRlc3RhdGlvbjAgFw0xNjAzMTQwMDAw
MDBaGA8yMDUyMDQxNzAwMDAwMFowJTEjMCEGA1UEAwwaWXViaUtleSBQSVYgQXR0
ZXN0YXRpb24gOWUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT1l76Mvo6dJ4CwX2QQ
HImYRWbxLqt1kCVsn0PUn20DYtSKLuq8kCnMAn+kdneqjtaaBmWuPJH+g7LMyI18
QDQp2w+qSOf9ZWrOupMAGM8EpWXNTSNKoE50JhKXFbudBByjTjBMMBEGCisGAQQB
gsQKAwMEAwUBAjAUBgorBgEEAYLECgMHBAYCBACDq1IwEAYKKwYBBAGCxAoDCAQC
AQIwDwYKKwYBBAGCxAoDCQQBBDANBgkqhkiG9w0BAQsFAAOCAQEAGSmu0PUMDfEb
PkmkJ/rKYvpOKhbmpryjXuZ7ENJ3jGq3foyLSN+aBbd3M1im2ejC6/upthcp1N5M
Mg2SN6MBRS4crtt43DVHepBPt2W07vW8h4uFosJX29HdhK0dP+RnBGDdWYo0nq7y
7q1Y1c0BI7oGnaORL0DzSDtdxAJAphjspWsWNCIP2DTWQPhLTg4DqmYd/ahygVsZ
IE64QvJDQC72Dfyad6tIajmtPncqPt857H0hEJv2X58iOoJA/wAeuId4or859cJU
GTDbN7Ke4LWXRbs7StJTgefmNgWmKjm1Q2qs80WGShyQ6OrxALejd8jivtcTwsDz
WvzdmHCOmg==
-----END CERTIFICATE-----
証明書のフィンガープリントは、証明書の生バイトに対して SHA1 チェックサムを実行し、そのチェックサムを 16 進文字列としてエンコードすることによって計算されます。
証明書のフィンガープリントを使用して、コミットとタグに署名するときにどの証明書を使用するかを git に知らせます:
FINGERPRINT=`pivit --print | head -1`
git config --(local|global) user.signingkey $FINGERPRINT
pivit -s [-a] [-b] [-u userid] [--status-fd=[num]] [-t url] [file]
-a (--armor) - 署名を ASCII アーマーでラップして印刷可能にするかどうか。-b (--detach-sign) - 分離署名を作成します。-u (--local-user) - メールアドレスか、16 進文字列としてエンコードされたキーフィンガープリントのいずれか。--status-fd - ステータスメッセージを出力するファイル記述子。1 は stdout、2 は stderr。0 以下の値は、ステータスメッセージが書き込まれないことを意味します。-t (--timestamp-authority) - タイムスタンプに使用する RFC3161 タイムスタンプ局の URL。file - 署名されるファイルへのパス。ファイル名が指定されていない場合は、stdin を使用します。このコマンドを実行すると Yubikey が点滅し、タッチされるまでブロックされます。
git がコミットとタグに署名するように設定されている場合、次のハードコードされたパラメータ -sbau [user.signingkey] --status-fd=1 が使用されます。
user.signingkey は git のローカル/グローバル設定から取得されます。
注記: Pivit は git コミットの署名をサポートするように設計されています。
ただし、使用中のキーが--pin-policy=alwaysを使用して作成された場合、完全にはサポートされない可能性があります。
現時点では、Pivit はコマンドライン経由でのみ PIN の入力を求めるプロンプトを表示します。GitKraken や SourceTree のような GUI ベースの git クライアントを使用している場合、そのプロンプトを見逃す可能性があります。
pivit --verify [file ...]
ファイル引数で指定された署名付きデータを検証します。
ファイルが指定されていない場合は、stdin から読み取ります。
ファイルパスが 1 つまたは 0 つ指定された場合は、署名が署名付きデータに添付されていると見なします。
それ以外の場合は、最初のファイルに署名が含まれ、2 番目のファイルに署名付きデータが含まれていると見なします。
署名付きデータを stdin から読み取ることを示すには、- を指定します。