It is recommended to store your keys in hardware wallets. It's one of the safest ways of creating signatures without exposing sensitive data. This guide will show you how to connect your hardware wallet in the CLI. It uses the PCKS11 standard for the communication.
We tested this configuration with a Ledger Nano S Plus. A different hardware wallet may require additional steps.
Install OpenSC
The OpenSC is a driver to connect with smart cards by using PKCS#11 standard.
Go to https://github.com/OpenSC/OpenSC/releases/latest to download the latest release and install the package.
After the installation you should see the library located at /Library/OpenSC/lib/opensc-pkcs11.so
in the case of MacOS/Linux, or at C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll
in the case of Windows.
If you have troubles with the installation please follow the quick start instructions documented in the official repo https://github.com/OpenSC/OpenSC/.
Configuration in EBSI CLI
If you use windows, go to the folder of the EBSI CLI tool and set the library in the .env file:
OPEN_SC_LIBRARY="C:\\Program Files\\OpenSC Project\\OpenSC\\pkcs11\\opensc-pkcs11.dll"
For MacOS or Linux it is not necessary since the default value is "/usr/local/lib/opensc-pkcs11.so".
Install and configure OpenPGP app
Install the Ledger Live app (https://www.ledger.com/ledger-live) and update the firmware to the latest version, or at least version 2.2.4. This step will probably require several updates of the firmware until it gets the latest one.
Go to settings -> experimental functions, and enable the developer mode.
Now go to My Ledger, search and install the "OpenPGP app". Its version should be >=2.3.0. Otherwise check again for updates in the firmware of Ledger.
Open the OpenPGP app in your ledger device. Go to "Settings" -> "Key template". Then set "Key" to "Signature" and "Type" to "SECP 256R1". And finally click on "Set Template".
Your hardware wallet is ready to be used in the EBSI CLI tool.
How to use the hardware wallet in EBSI CLI
Run "hardwarewallet info" to see the details of your device:
==> hardwarewallet info
{
"slot": 0,
"description": "Ledger Nano S Plus 0",
"serial": "2c97200e4c5e",
"password": {
"min": 6,
"max": 12
},
"isHardware": true,
"isRemovable": true,
"isInitialized": true
}
Now generate a new key:
==> hardwarewallet generateKey
Key pair generated successfully!
Get the public key already generated:
==> hardwarewallet publickey
{
"kty": "EC",
"crv": "P-256",
"x": "FvfSizOfrGkq-xti3FidtNLuduqmHGyoWWcm1hRfhhY",
"y": "o7rRs9f9zUWBorH2CHDh-M7HHhJt1ua2207Jqfy6kHg"
}
You already generated a ES256 key pair in your the device. No need to generate it again next time you open the CLI.
Connect the wallet to the user
When you load the keys of your user in the CLI, use the word "hardwarewallet" in the place where you normally enter the private key. Also, use this only with the ES256 alg:
==> using user ES256 did1 hardwarewallet
Update your DID document
Remember to update your DID document with this new ES256 key. If you already have an ES256 key in your DID document, follow these instructions to add another one.
Load your user and keys as usual:
==> using user ES256K did1 PRIVATE_KEY_ES256K
==> using user ES256 did1 PRIVATE_KEY_ES256
Save the new public key in a variable:
pubkey: hardwarewallet publickey
{
"kty": "EC",
"crv": "P-256",
"x": "FvfSizOfrGkq-xti3FidtNLuduqmHGyoWWcm1hRfhhY",
"y": "o7rRs9f9zUWBorH2CHDh-M7HHhJt1ua2207Jqfy6kHg"
}
Value saved in 'pubkey':
{
"kty": "EC",
"crv": "P-256",
"x": "FvfSizOfrGkq-xti3FidtNLuduqmHGyoWWcm1hRfhhY",
"y": "o7rRs9f9zUWBorH2CHDh-M7HHhJt1ua2207Jqfy6kHg"
}
Compute the corresponding thumbprint and save it in a variable:
vMethodId: compute thumbprint pubkey
Request an access token and update the DID document by using this key:
# Request access token
authDidWrite: authorisation auth didr_write_presentation ES256
using token authDidWrite.access_token
# Add the new key
did addVerificationMethod user.did pubkey vMethodId
# Add the relationships
did addVerificationRelationship user.did authentication vMethodId
did addVerificationRelationship user.did assertionMethod vMethodId
Check if the DID document was correctly updated:
did get /identifiers/ user.did
Now load your user again using the key from the hardware wallet:
using user null
using user ES256K did1 PRIVATE_KEY_ES256K
using user ES256 did1 hardwarewallet
You already connected your user with the hardware wallet and updated the respective DID document. Now you can sign credentials as usual.