🔑

OpenSCでThales eToken 5110上にキーペアを生成してCSRを提出する

2025/03/04に公開

この記事は、既に手元にあるThales製のSafeNet eToken 5110 CC (940)上に、OpenSCを用いて新しくキーペア(秘密鍵及び公開鍵)及びCSR(Certificate Signing Request)を生成する方法を紹介します。

SafeNet eToken 5110

eToken 5110シリーズは、USBトークンによるプロビジョニング方法を選んだ場合に、DigiCertやSectigoなどの様々な商用CA(Certificate Authority:認証局)が配送する物理USBトークンです。主に、HSM(Hardware Security Module)デバイス上で管理することが義務付けられているEV(Extended Validation)証明書をオーダーする際に、CAが配送するeTokenではなく、既に手元にある新品若しくは再利用としてのeTokenを使用したい場合に有効です。

特に、YubiKey 5のFIPSシリーズはRSA2048までしかサポートしておらず、Thales製のeTokenは重宝します。

https://cpl.thalesgroup.com/en-gb/access-management/authenticators/pki-usb-authentication/etoken-5110-usb-token

OpenSC

OpenSCは、スマートカードを利用した認証や暗号化機能を提供するオープンソースのライブラリおよびツールセットです。PKCS#11、PKCS#15、ISO 7816 などの標準規格をサポートし、さまざまなスマートカードやセキュリティトークンと連携できます。今回は、PKCS#11を扱うことになります。

OpenSCのインストールについては、公式リポジトリのWikiを参考にしてください。

https://github.com/OpenSC/OpenSC

SafeNet Authentication Client

SAC(SafeNet Authentication Client)は、公開鍵暗号を基盤とした安全な情報交換を提供するPKI(公開鍵基盤)ミドルウェアです。

インストールについては、各CAのドキュメントを確認してください。SACのインストールには、OpenSCを介してeTokenを操作する際に必要なモジュールが含まれています。PKCS#11に関する操作では、SACインストール時に%system32%及びSysWOW64に配置されるeTPKCS11.dllが必要となります。

https://cpl.thalesgroup.com/access-management/security-applications/authentication-client-token-management

ハードウェアテスト

--testでハードウェアテストを行い、eTokenデバイスが正常に動作していることを確認します。

pkcs11-tool --module "eTPKCS11.dll" --test --login
Using slot 0 with a present token (0x0)
Logging in to "My Token".
Please enter User PIN: C_SeedRandom() and C_GenerateRandom():
  seems to be OK
Digests:
  all 4 digest functions seem to work
  SHA-1: OK
  SHA256: OK
Ciphers: not implemented
Signatures (currently only for RSA)
Signatures: no private key found in this slot
Verify (currently only for RSA)
  No private key found for testing
Decryption (currently only for RSA)
No errors

キーペア生成

RSA4096のキーペア(秘密鍵及び公開鍵)を生成します。Private Key Objecturiは後で必要になるのでメモしておきます。

pkcs11-tool --module "eTPKCS11.dll" --login --keypairgen --key-type RSA:4096 --label "csev" --id 01
Using slot 0 with a present token (0x0)
Key pair generated:
Private Key Object; RSA
  label:      csev
  ID:         01
  Usage:      decrypt, sign, unwrap
  Access:     sensitive, always sensitive, never extractable, local
  uri:        pkcs11:model=ID%20Prime%20MD;manufacturer=Gemalto;serial=0000000000000000;token=My%20Token;id=%01;object=csev;type=private
Public Key Object; RSA 4096 bits
  label:      csev
  ID:         01
  Usage:      encrypt, verify, wrap
  Access:     local
  uri:        pkcs11:model=ID%20Prime%20MD;manufacturer=Gemalto;serial=0000000000000000;token=My%20Token;id=%01;object=csev;type=public

--list-objectsで生成された秘密鍵オブジェクトの情報を確認できます。

pkcs11-tool --module "eTPKCS11.dll" --login --list-objects --type privkey

ここで、生成された秘密鍵をテストして正常に動作していることを再度確認します。

pkcs11-tool --module "eTPKCS11.dll" --test --login

CSRの生成

SACにはキーペアの生成やCSRの生成を行う機能はありません。ここからは、OpenSCとOpenSSLを用いて、それぞれキーペアとCSRを生成します。

OpenSSLについては、デフォルトでPKCS#11エンジンがサポートされていないため、個別にビルドする必要があります。

libp11のビルド(Win64)

git clone https://github.com/OpenSC/libp11.git
cd libp11
git checkout libp11-0.4.13
nmake /f Makefile.mak OPENSSL_DIR="C:/path/to/openssl" BUILD_FOR=WIN64

正常にビルドが終ると、src/に2つのDLLが生成されます。

Get-ChildItem -Name -Filter "src/*.dll"

libp11.dllpkcs11.dllを任意の場所に配置します。ここでは、C:/libp11に配置します。

OpenSSLがこれらのモジュールを正常に読み込めていることを確認します。

openssl engine dynamic \
  -pre "SO_PATH:C:\libp11\pkcs11.dll" \
  -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD \
  -post "MODULE_PATH:C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll"

OpenSSLにPKCS#11モジュールを追加

さらに、OpenSSLのbinにあるopenssl.cfgを編集します。個別のコンフィグファイルとして記述してコマンドラインで指定しても問題ありません。

%System32%eTPKCS11.dllがあることを確認します。

openssl.cfg
+openssl_conf = openssl_init
openssl.cfg
+[openssl_init]
+engines = engine_section

+[engine_section]
+pkcs11 = pkcs11_section

+[pkcs11_section]
+engine_id = pkcs11
+dynamic_path = "C:\\libp11\\pkcs11.dll"
+MODULE_PATH = "C:\\Windows\\System32\\eTPKCS11.dll"
+init = 0

PKCS#11モジュールが問題なく認識されていることを確認します。

openssl engine -t
openssl engine pkcs11 -t
(pkcs11) pkcs11 engine
     [ available ]

CSRを生成

生成した秘密鍵で署名されたCSRを生成します。-keyには秘密鍵へのuriを指定します。

openssl req \
  -new \
  -subj '/C=JP/ST=Tokyo/L=Shibuya/CN=My Company' \
  -sha256 \
  -engine pkcs11 \
  -keyform engine \
  -key "pkcs11:model=ID%20Prime%20MD;manufacturer=Gemalto;serial=0000000000000000;token=My%20Token;id=%01;object=csev;type=private" \
  -out my.csr

証明書のマージ

CSRをCAに送り、これが署名されると、PEM形式の証明書がCAから送付されます。最後にこれをeTokenにマージします。

pkcs11-tool \
  --module "eTPKCS11.dll" \
  --login \
  --write-object my.crt \
  --type cert \
  --label "csev" \
  --id 01

署名

パワーシェルスクリプトを署名してみます。signtoolはデフォルトで最適な証明書を選択しますが、複数の証明書が存在する場合、/aで選択すべき証明書のsha1を明示的に指定します。

signtool \
  sign \
  /sha1 D6846A11501FDEB5B420B0C91C2C4572BDD8F035 \
  /tr http://timestamp.digicert.com \
  /td sha256 \
  /fd sha256 \
  my.ps1

正常に署名されていることを確認します。

my.ps1
echo "hello world"

# SIG # Begin signature block
# MIIhCAYJKoZIhvcNAQcCoIIg+TCCIPUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# ...
# SIG # End signature block

Discussion