Pico HSM supports in place signatures of arbitrary data. It supports the following algorithms:
Typically, there are two major signature algorithms: RSA and ECDSA. RSA uses RSA keys to encrypt with the private key some particular data, the signature, which can be later verified by using the public key. ECDSA follows the same principle but it uses elliptic curves instead. The signature algorithm is more sophisticated and allows faster and optimized signatures and verifications.
The PKCS variant, also known as v1.5, is the first release of the signature algorithm for RSA keys. It allows the use of raw data or prehashed with SHAx digest. The PSS variant is more secure and more robust algorithm for RSA signatures. It also accepts raw or prehashed data with SHAx digest. The X-509 variant is a particular case, where the data is prepended with an ASN.1 structure that contains all the necessary parameters.
ECDSA, fortunately, is much simpler and there is only one algorithm, with prehashed data with SHAx digest.
Preliminar
Before going to the signature, we prepare the data. In the file data
we put some arbitrary data:
$ echo "This is a test string. Be safe, be secure." > data
To create the signatures, we use the OpenSSL tool. This tool requires the use public keys in the form of DER and PEM, which will be used for verification. In our example, we employ the RSA located at key id 1:
$ pkcs11-tool --read-object --pin 648219 --id 1 --type pubkey > 1.der
$ openssl rsa -inform DER -outform PEM -in 1.der -pubin > 1.pub
The --id
parameter identifies the internal private key with id number 1
. The first line retrieves the public key associated to the private key with id number 1
and stores the public key into the file 1.der
.
The second line converts the public key from DER format to PEM.
RSA-PKCS
This algorithm is used to sign raw data.
To sign the data:
$ pkcs11-tool --id 1 --sign --pin 648219 --mechanism RSA-PKCS -i data -o data.sig
The signature requires the use of private key, which is stored inside the Pico HSM. With the --id
parameter, we are telling the Pico HSM which private key shall be used to sign the data contained in the file.
After the command, the signature is saved in the data.sig
file. To verify the signature:
$ openssl pkeyutl -verify -pubin -inkey 1.pub -in data -sigfile data.sig
Signature Verified Successfully
CAUTION: the RSA-PKCS works with raw data, which means that all data is transferred to the Pico HSM through USB interface. If the data is large, it may break the connection. Hence, it is only recommended to use this variant with very small chunks of data. Use variants with digest computation outside whenever you can.
SHA1-RSA-PKCS
This algorithm is used to sign digests computed outside. It supports SHA1, SHA224, SHA256, SHA384 and SHA512.
First, we generate a file with the digest:
openssl dgst -sha1 -binary -out data.sha1 data
To sign the data:
$ pkcs11-tool --id 1 --sign --pin 648219 --mechanism SHA1-RSA-PKCS -i data -o data.sig
To verify the signature:
$ openssl pkeyutl -verify -in data.sha1 -sigfile data.sig -pubin -inkey 1.pub -pkeyopt digest:sha1
Signature Verified Successfully
RSA-X-509
This algorithm is used for signing raw data. In this algorithm, the data must be padded with a length equal to the size of private key (128, 256, 512 bytes for RSA-1024, RSA-2048 and RSA-4096, respectively).
First, we pad the data. The original data file occupies 29 bytes. Thus, for a 2048 bits key, a padding of 227 bytes is needed:
$ cp data data_pad
$ dd if=/dev/zero bs=1 count=227 >> data_pad
To sign the data:
$ pkcs11-tool --id 1 --sign --pin 648219 --mechanism RSA-X-509 -i data_pad -o data.sig
To verify the signature:
$ openssl rsautl -verify -inkey 1.pub -in data.sig -pubin -raw
This is a test string. Be safe, be secure.
RSA-PKCS-PSS
This algorithm uses the RSA-PKCS with PSS salt to randomize the signature. Pico HSM does not support arbitrary salt lengths. Instead, it always uses the maximum salt length (the hash length). It uses the hash as the input.
To sign the data:
$ pkcs11-tool --id 1 --sign --pin 648219 --mechanism RSA-PKCS-PSS -i data.sha1 -o data.sig
To verify the signature:
$ openssl pkeyutl -verify -in data.sha1 -sigfile data.sig -pubin -inkey 1.pub -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:-1 -pkeyopt digest:sha1
Signature Verified Successfully
SHA1-RSA-PKCS-PSS
This algorithm takes the file as the input and sends its hash for signing with the random salt.
To sign the data:
$ pkcs11-tool --id 1 --sign --pin 648219 --mechanism SHA1-RSA-PKCS-PSS -i data -o data.sig
To verify the signature:
$ openssl pkeyutl -verify -in data.sha1 -sigfile data.sig -pubin -inkey 1.pub -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:-1
Signature Verified Successfully