Key Infrastructure and PIN codes for Wallets
This page explains how Venly securely manages the keys for the created wallets and provides some recommendations on how to handle the Wallet PIN codes.
Venly creates a private and public keypair whenever a Wallet is created through the API. The
public keyis the Wallet address (e.g.
0x123123123) and the
private keyis the "password" to this wallet.
Knowing the private key will give you access to all digital assets linked to this wallet. The private key is therefore securely stored in our system. The following diagram explains the steps.
The private key is first encrypted with a random passphrase. The passphrase is then split into three different shares, using the Shamir Secret Sharing algorithm.
- User-owned share: This is the share in sole ownership of the user. The share gets extra encryption with a secret chosen by the user (i.e. the PIN code provided during wallet creation). The encrypted user-owned share is then securely stored in a Key-Vault. Because of the extra encryption, only the user is able to access this share. Only when the PIN code is provided, can the user-owned share be decrypted and used to access the private key (together with the application share).
- Application share: A share owned by Venly and securely stored in a Key-Vault.
- Recovery share: A share used to recover the private key, whenever the user lost its PIN code. This share will only be created when you create
RECOVERABLEwallets (custodial wallets). This share is stored on cold storage (not connected to the internet).
To access the private key, ownership has to be proven of at least 2 shares. In the common case, this will be the user-owned share (where the user has provided their PIN code, so it can be decrypted) and the application share. Both are used to reconstruct the passphrase and decrypt the private key. Hereafter the private key can be used to execute the requested function (e.g. performing a crypto transfer).
All shares are encrypted and securely stored in a "Vault" (Key Management system).
You are always able to export the private key of a created wallet if you like (e.g. to provide it to the user).
Whenever you create a wallet a PIN code needs to be provided. This PIN code is used to encrypt the user-owned share (see above). This PIN code should be provided each time you interact with the created wallet. It is a "secret" and should therefore be securely managed at your side.
Below are a couple of recommendations for managing the PIN code, based on different use cases.
In this case, you expose the PIN code functionality to the end user. The user needs to provide the PIN code when a wallet is created, and you pass this PIN code to our create-wallet-endpoint.
Each time you want to interact with the created wallet, user interaction is needed. The user will need to provide the PIN code, and you pass this PIN code to the necessary endpoint.
Your app, therefore, does not need to store any PIN information. It only passes the PIN code from user to Venly.
This is a recommended way of working, as it minimizes the security points of failure. No sensitive information is stored on your systems. Only the communication lines between user-your app-Venly need to be secured.
When you do not like to expose the PIN code functionality, but still require a secure way of working. Encrypting and storing the PIN code with a user-known secret works as well.
In this case, the wallet creation flow works as follows:
- 1.Your app generates a random PIN code
- 3.You encrypt the generated PIN code with a user-known secret (e.g. a password they provide, or their biometrics, ...)
- 4.You store the encrypted PIN code.
To interact with a wallet, the following flow is needed:
- 1.Let the user enter their user-known secret (password, biometric, ...)
- 2.Decrypt the stored encrypted PIN code with the provided user-secret
- 3.Use the decrypted PIN code to call the necessary Venly-endpoint.
In this way of working, you do store the PIN codes (in encrypted form). Wallet interaction still requires user interaction. Compared with the first case, in this flow, you have full control on how that user interaction looks like (user enters a password, face-id, ...)
Another option is to set a master PIN for every wallet that you create for your end users. The end user is not involved when choosing/setting the PIN code.
This method allows you to interact with the wallets without user interaction. For example: with this way of working, you can create functionality for periodic payments: every period, a transfer is triggered on the user's wallet.
We recommend this method only when you really need interaction with the wallets, without user interaction. Setting a master PIN for every created wallet adds a security risk.
This option is only possible if you create custodial wallets. For non-custodial wallets, user interaction is always required.