Andreas Schwier | 20 Jun 2022
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 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