Most smart cards compatible with OpenSC will offer only RSA 1024 bits key usage. Some will offer also RSA 2048 bits, but only very few do more. The OpenPGP card and the Cryptostick are known to be able to handle 4096 bits keys. However, the storage capacity of the OpenPGP is quite limited and the Cryptostick isn't available anymore (a new version is in beta, though).
Elliptic Curve Cryptography done on smart cards is very rare. And this is where the SmartCard-HSM stands out and it even works with OpenSC!
In this article I will only cover on initializing the tokend and usage of simple RSA keys, the usage on ECC is for a future post.
Unfortunately not all of the patches have made it in OpenSC 0.13.0 for properly supporting the SmartCard-HSM. The first issue I've encountered was the inability to work with RSA keys of 2048 bits.
A similar issue is present for EC keys and requires OpenSC 0.14 for it to work. Ubuntu Vivid (15.04) and Debian Jessie will include 0.14, but for any current Ubuntu version you can install the backports I've compiled in my opensc-backports PPA.
For Debian support, the maintainer decided not to backport the fixes to Wheezy (7.x). The Jessie (8.x) release includes 0.14 and should be all fine.
First, choose a SO-PIN of exactly 16 hexadecimal characters. It will be stored internally as an 8-byte key.
My recommendation is to store the SO PIN in a very safe place.
Secondly, make up a (user) PIN. It can be of any length from four up to sixteen ASCII characters with an important limitation listed below.
Any further reinitialization of the card will require you to enter the SO PIN. Unlike other smart cards or tokens, you cannot erase the card without the knowledge of the SO PIN!
The counter for wrong-entered SO PINs is 15 and is not unblockable. So, yes, entering the SO PIN wrong for 15 times renders the card unusable forever.
The initialization tool only takes SO PIN and PIN using command line arguments (opposed to reading from keyboard interactively). Any user on the system can see these secrets by doing a full process listing on the machine. You may want to run the initialization in an offline Live CD environment. Also, the full PINs will end up in your shell history. Bash allows you to omit this by prepending the command with a space.
Card versions up to 1.0 will not allow you to change this SO PIN ever again. To check your card version, run
pkcs11-tool -L, e.g.:
$ pkcs11-tool --module opensc-pkcs11.so -L
While the (User) PIN can be changed, it's not allowed to change it to another size (length). Andreas Schwier of CardContact confirmed this unfortunate restriction in private communication while noting that this holds for cards at least up to and including card version 1.2. Changing the size of the PIN currently requires reinitialization of the card (wiping its contents!).
Initialize using the
sc-hsm-tool command shipped with OpenSC:
# DO NOT CONTINUE UNLESS YOU'VE READ THE WARNINGS LISTED ABOVE # prepend the command with a space to avoid saving in bash history $ sc-hsm-tool --initialize --so-pin 0123012301230123 --pin abcdABCD12349876
Unfortunately, it's not (yet) possible to initialize the card using the more generic
To create an RSA keypair of 2048 bits (maximum size for SmartCard-HSM) use
pkcs11-tool like this:
$ pkcs11-tool --module opensc-pkcs11.so -l --keypairgen --key-type rsa:2048 --id 10 --label "My first RSA keypair"
It will ask for your PIN and the keypair will be generated on-card. I've made up an ID and label here; choose your own.
To see the keypair listed, you could use
$ pkcs11-tool --module opensc-pkcs11.so --list-objects Using slot 1 with a present token (0x1) Public Key Object; RSA 2048 bits label: My first RSA keypair ID: 10 Usage: none
Note it lists
This really should be something like
Usage: encrypt, verify, wrap.
I'm not sure what's going on here, but I am able to use the public key to encrypt data.
$ pkcs15-tool --read-public-key 10 > /tmp/publickey.pem
10 is the ID of the object.
In case you see
error: object not found
RSA is not meant to encrypt/decrypt large amounts of data. 245 bytes is the maximum message length for a 2048 bits key as described in an earlier article: How to encrypt a LUKS container using a smart card or token.
Create a random piece of data and hash it so we can identify it's the same later:
$ dd if=/dev/urandom of=/tmp/mydata bs=1 count=245 $ sha256sum /tmp/mydata
Encrypt the data using the public key, in a PKCS#1 padding:
$ openssl rsautl -inkey /tmp/publickey.pem -pubin -encrypt -pkcs -in /tmp/mydata -out /tmp/encrypteddata.pkcs1
Decrypt the data again using the smart card:
$ pkcs15-crypt --decipher --key 10 --input /tmp/encrypteddata.pkcs1 --pkcs1 --raw > /tmp/decrypteddata $ sha256sum /tmp/decrypteddata
Many many applications can be found for using any smart card or token. On some of them I have written (or will write later):
- Disk encryption using LUKS
- SSH publickey authentication
- Set up your own PKI
- Second-factor in workstation login
- E-mail encryption/signing
- SSL Client authentication on web servers
- OpenSC wiki page on SmartCard-HSM
- OpenSC on GitHub and the fork by CardContact
- SmartCard-HSM product flyer (PDF)