I have a Gemalto SafeNet eToken with an eIDAS Qualified Electronic Seal (also known as an e-Seal, Digital Stamp, or Document Signing Certificate) issued by SK ID Solutions. I want to sign a SHA-256 hash using this token.
Step 1: Check keypair information
We need the token label (or slot ID 8
, which is 0x11
) and the public key ID (00000000
) for signing and verifying.
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so -L
Sample output:
Slot 8 (0x11): SafeNet eToken 5100 [eToken 5110 SC] 01 (Digital Signature Pin)
token label : eID Easy (Digital Signature Pin)
token manufacturer : Gemalto
token model : ID Prime MD
token flags : login required, rng, token initialized, PIN initialized, other flags=0x200
hardware version : 0.0
firmware version : 0.0
serial num : 06E2CF0B29CA6BD0
pin min/max : 4/16
Get public key and certificate details:
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so --token-label "eID Easy (Digital Signature Pin)" -O
Sample ouput:
Certificate Object; type = X.509 cert
label:
subject: DN: organizationIdentifier=NTREE-14080014/serialNumber=14080014, ST=Harjumaa, L=Tallinn, C=EE, O=EID Easy OÜ, CN=eID Easy
ID: 00000000
Public Key Object; RSA 2048 bits
label: eID Easy
ID: 00000000
Usage: verify, wrap
Access: local
Step 2: Prepare digest
Assuming you already have a SHA-256 hash in hexadecimal format:
$ echo "19d512fc649e1668eb84741284ad95ec03f3225719a83e40389dbade4eabe5ed" > digest.txt
$ xxd -r -p digest.txt digest.bin
Step 3: Sign the digest
Use pkcs11-tool
with RSA-PKCS
, which signs raw binary input (not a digest calculation itself).
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so --pin=$PIN --token-label "eID Easy (Digital Signature Pin)" -s -i digest.bin -m RSA-PKCS > signature.bin
View signature in base64:
$ base64 signature.bin -w0
Sample output (your actual signature will differ):
RseZYWjkyNRcU1lI1KR+I+0C1jC+FVp2kTAhyOUsE2x6UGf+UMSf3kqD4KGBb+eI...
Step 4: Verify the signature
Extract the public key:
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so --token-label "eID Easy (Digital Signature Pin)" --read-object --type pubkey --id=00000000 > public-key.der
$ openssl rsa -inform DER -outform PEM -in public-key.der -pubin > public-key.pem
Verify the signature and extract original digest:
$ openssl rsautl -verify -inkey public-key.pem -in signature.bin -pubin > verified.bin$ xxd -p -c32 verified.bin > verified.txt
Compare digests:
$ cat digest.txt verified.txt
Expected output:
19d512fc649e1668eb84741284ad95ec03f3225719a83e40389dbade4eabe5ed19d512fc649e1668eb84741284ad95ec03f3225719a83e40389dbade4eabe5ed
Notes on Supported Signature Mechanisms
The token supports a range of mechanisms including raw RSA and hashed variants with/without PSS padding:
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so -M --slot 0x11 | grep sign
Sample output:
RSA-PKCS
RSA-PKCS-PSS
SHA256-RSA-PKCS
SHA256-RSA-PKCS-PSS
SHA384-RSA-PKCS
SHA384-RSA-PKCS-PSS
SHA512-RSA-PKCS
SHA512-RSA-PKCS-PSS
...
RSA-PKCS
: Signs raw binary input, no hashing.SHA256-RSA-PKCS
: Hashes with SHA-256 before signing.SHA256-RSA-PKCS-PSS
: Hashes and uses randomized PSS padding (non-deterministic signature).