🐕

Yubico PIV Tool による YubiKey を利用した署名

2022/12/01に公開

Digital Identity技術勉強会 #iddance Advent Calendar 2022 2 日目の記事です。

https://qiita.com/advent-calendar/2022/iddance

本投稿では、Yubico PIV Tool [1]により、YubiKey を利用してテキストデータなどに署名を行う方法を説明します。
なお、本投稿では署名に絞って動作を記載しますが、Yubico PIV Tool には署名に限らず様々な機能が含まれています。もし、興味がある方は適宜原文をご確認いただけますと幸いです。

はじめに

まず、Yubico PIV Tool の取得方法および当該ツールのドキュメントの記載内容について簡単に触れておきます。

Yubico PIV Tool は、公式ページの Releases[2]から OS ごとのパッケージが取得できるようになっており、ここから取得するのが最も簡単な方法だと思います。
なお、GitHub リポジトリ[3]も公開されており、ソースコードからビルドすることもできるようですが、例えば、以下のような依存パッケージが必要である点に注意してください。

cmake libtool libssl-dev pkg-config check libpcsclite-dev gengetopt help2man

公式ドキュメント[4]に記載の通り、YubiKey には用途の異なる複数のキースロットが存在しています。例えば、以下の通り、署名のスロットは 9c になっており、用途に応じたスロットを事前に確認する必要があります。

-s, --slot=ENUM
What key slot to operate on (possible values="9a", "9c", "9d", "9e", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "f9")

9a is for PIV Authentication 9c is for Digital Signature (PIN always checked) 9d is for Key Management 9e is for Card Authentication (PIN never checked) 82-95 is for Retired Key Management f9 is for Attestation

また、上記の通り、スロットによっては PIN を常に要求されます。YubiKey の PIN を設定された覚えのない方もいらっしゃるかと思いますが、公式ドキュメント[1:1]に記載の通り、デフォルトの PIN は 123456 になっています。

The default PIN code is 123456. The default PUK code is 12345678.

署名

Yubico PIV Tool による署名は、公式ドキュメントの Signing[5] に記載の手順に沿って行うことができます。
なお、自分が確認した時点において、事前にスロット 9c に鍵をインポートしていない場合、署名する際に 6a80 というエラーコード[6]が返ってくる状況でした。したがって、ここでは PKCS#12 形式のファイルをインポートするところから実施します。

鍵の作成

公式ドキュメント[5:1]に記載の通り、利用可能なアルゴリズムは RSA1024、 RSA2048、 ECCP256、 ECCP384 となっています。
例えば、ブログ[7]に記載の手順に沿って、以下のようにコマンドを実行していくことで、アルゴリズム ECCP256 で PKCS#12 形式のファイルが作成できました。

# generate a private key for a curve
$ openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem

# generate corresponding public key
$ openssl ec -in private-key.pem -pubout -out public-key.pem

# optional: create a self-signed certificate
$ openssl req -new -x509 -key private-key.pem -out cert.pem -days 360

# optional: convert pem to pfx
$ openssl pkcs12 -export -inkey private-key.pem -in cert.pem -out cert.pfx

インポート

公式ドキュメント[4:1]に記載の以下の通り PKCS#12 形式のファイルをスロット 9c にインポートします。

Set a random chuid, import a key and import a certificate from a PKCS12 file, into slot 9c:

yubico-piv-tool -s9c -itest.pfx -KPKCS12 -aset-chuid
-aimport-key -aimport-cert

実行結果の例は以下の通りになります。

$ yubico-piv-tool -s9c -icert.pfx -KPKCS12 -aset-chuid \
                       -aimport-key -aimport-cert
Successfully set new CHUID.
Enter Password:
Successfully imported a new private key.
Successfully imported a new certificate.

署名および検証

ここまでの手順で署名を行う準備ができたので、公式ドキュメント[5:2]に記載の手順に沿って、署名及び検証を行います。
ファイルに対して署名および検証を実施した際の実行結果の例は以下の通りです。

$ yubico-piv-tool -a verify-pin --sign -s 9c -H SHA256 -A ECCP256 -i data.txt -o data.sig
Enter PIN:
Successfully verified PIN.
Signature successful!

$ openssl dgst -sha256 -verify public-key.pem -signature data.sig data.txt
Verified OK

また、標準入力に対して署名を行い、シグネチャを標準出力する際は、例えば以下のように実行します。

$ echo 'test' | yubico-piv-tool -a verify-pin --sign -s 9c -H SHA256 -A ECCP256 -i - -
Enter PIN:
Successfully verified PIN.
0D
���
Signature successful!
�$� %#���A�\�.$�C����q����2��⏎

おわりに

本投稿では、Yubico PIV Tool により、YubiKey を利用してテキストデータなどに署名を行う方法を説明しました。
YubiKey のユースケースが広がっていくことで、鍵管理などに関する懸念を YubiKey に任せることができるシーンも増えてくるかもしれません。
明日投稿予定の記事では、実際のアプリケーションに本日紹介した機能を組み込む際の例を紹介させてもらえればと思います。
ではまた。

脚注
  1. Yubico PIV Tool https://developers.yubico.com/yubico-piv-tool/YubiKey_PIV_introduction.html ↩︎ ↩︎

  2. Releases https://developers.yubico.com/yubico-piv-tool/Releases/ ↩︎

  3. GitHub Yubico PIV Tool https://github.com/Yubico/yubico-piv-tool ↩︎

  4. SYNOPSIS https://developers.yubico.com/yubico-piv-tool/Manuals/yubico-piv-tool.1.html ↩︎ ↩︎

  5. Signing https://developers.yubico.com/yubico-piv-tool/Actions/signing.html ↩︎ ↩︎ ↩︎

  6. PKCS8 cert fails to sign with code 6a80 https://github.com/Yubico/yubico-piv-tool/issues/222 ↩︎

  7. Creating Elliptic Curve Keys using OpenSSL https://www.scottbrady91.com/openssl/creating-elliptical-curve-keys-using-openssl ↩︎

GitHubで編集を提案

Discussion