Using the SmartCard-HSM with PGP
Andreas Schwier | 20 Jun 2022
Pretty Good Privacy (PGP) is a common standard for file and e-mail encryption and signing. The GNU Privacy Guard (GnuPG) is a free software commonly used on Linux systems and on Windows.
GnuPG supports the OpenGPG card, however that uses an APDU interface incompatible with the SmartCard-HSM. The current support for the SmartCard-HSM in GnuPG is limited to gpgsm, which is the part of GnuPG that uses X.509 certificates. But GnuPG is not the only implementation of OpenPGP, another popular option is the OpenPGP implementation in the Bouncy Castle Crypto Library. In our own Java based sc-hsm-pgp tool we use that in combination with the SmartCard-HSM JCE-Provider.
The sc-hsm-pgp command line tool is contained in the SmartCard-HSM Starterkit. The source code can be found in the CDN.
The jar requires Java to be installed on the system. Entering
asc@caprese:~/tmp/pgp$ java -jar sc-hsm-pgp.jar -?
The SmartCard-HSM PGP Frontend 1.0
Usage: java -jar sc-hsm-pgp.jar [mode] [options]
shows a short help menu.
Before using the sc-hsm-pgp you need to generate a RSA key on the SmartCard-HSM. You can either use the key manager from the Smart Card Shell or pkcs11-tool from OpenSC:
asc@caprese:~/tmp/pgp$ pkcs11-tool --login --pin 648219 --keypairgen --key-type rsa:2048 --label PGP
Using slot 1 with a present token (0x4)
Key pair generated:
Private Key Object; RSA
label: PGP
ID: 1fbcffc67940bd4fc02e496ea9e0fbb958efecde
Usage: decrypt, sign
Access: none
Public Key Object; RSA 2048 bits
label: PGP
ID: 1fbcffc67940bd4fc02e496ea9e0fbb958efecde
Usage: encrypt, verify
Access: none
Next you will need to export the public key in the GnuPG format:
asc@caprese:~/tmp/pgp$ java -jar sc-hsm-pgp.jar --export --key PGP --id foo@bar --pin 648219 --output pubkey.pem
Getting key for alias PGP...
Adding user foo@bar to public key...
Writing public key to pubkey.pem...
The resulting public key can then be imported into your public keyring:
asc@caprese:~/tmp/pgp$ gpg --import pubkey.pem
gpg: key B8CB33977D15C29C: public key "foo@bar" imported
gpg: Total number processed: 1
gpg: imported: 1
The public key is now in your keyring:
asc@caprese:~/tmp/pgp$ gpg --list-keys
/home/asc/tmp/pgp/pubring.kbx
-----------------------------
pub rsa2048 1970-01-01 [SCEA]
5E3DFDE2343D2BC8B29617C0B8CB33977D15C29C
uid [ unknown] foo@bar
Please note, that the key creation date is always set to 1970-01-01. This is because the key meta data in the SmartCard-HSM does not provide the key creation time.
To encrypt a file you can use:
asc@caprese:~/tmp/pgp$ gpg --encrypt -r foo@bar plain
gpg: B8CB33977D15C29C: There is no assurance this key belongs to the named user
pub rsa2048/B8CB33977D15C29C 1970-01-01 foo@bar
Primary key fingerprint: 5E3D FDE2 343D 2BC8 B296 17C0 B8CB 3397 7D15 C29C
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
Use this key anyway? (y/N) y
You get the warning, because the key is currently not trusted. You can start gpg with –edit-key foo@bar and enter “trust”.
The encrypted files can then be decrypted using the key on the SmartCard-HSM:
asc@caprese:~/tmp/pgp$ java -jar sc-hsm-pgp.jar --decrypt --key PGP --pin 648219 --file plain.gpg --output plain.recovered
Getting key for alias PGP...
Setup decryption...
Decrypting data...
Data decrypted!
asc@caprese:~/tmp/pgp$ cat plain.recovered
Hello World
You can also sign with the key on the SmartCard-HSM:
asc@caprese:~/tmp/pgp$ java -jar sc-hsm-pgp.jar --sign --key PGP --id foo@bar --pin 648219 --file plain --output plain.signed
Getting key for alias PGP...
Generate Signature...
Compress data...
Writing signed data to plain.signed...
The signed file can then be verified using the public key in your keyring:
asc@caprese:~/tmp/pgp$ gpg --homedir . --verify plain.signed
gpg: Signature made Mi 20 Jul 2022 16:08:40 CEST
gpg: using RSA key B8CB33977D15C29C
gpg: issuer "foo@bar"
gpg: Good signature from "foo@bar" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 5E3D FDE2 343D 2BC8 B296 17C0 B8CB 3397 7D15 C29C