The most important piece of information for every Ethereum wallet owner, is the private key. It is the most important because loss of that private key will result in the owner not being able to access the tokens associated to that wallet, without any possibility of recovery.
In some blockchain based scenarios, a centralized and secured wallets management solution is required, usually to allow users to use a dedicated wallet inside the boundaries of the system, without risking their private wallets.
Azure Key Vault, and even more so, its hardware security modules (HSM) offering, allows management and usage of cryptographic key pairs, without the private key ever leaving the vault, unless it’s for backup and restore operations, meaning, the risk of loss or exposure of the private key is reduced.
A complete example with both a Terraform script for deploying the required infrastructure (an Azure Key Vault, a Function App, and some additionally required resources), and an Azure Functions App with two functions for creating wallets and singing, can be found in this GitHub repository:
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or…
For this article, we will be using Terraform to deploy all the resources we require for our simple Ethereum wallets manager, which include:
- A storage account required by the functions app.
- A key vault for storing wallet keys.
- And lastly, a functions app that will act as a gateway to the vault.
For brevity, I will only go over the areas of the Terraform script that specifically handle the creation of the vault, the functions app and the policy that allows the app to access the vault.
We will start by the adding an
azurerm_key_vault resource with a
premium SKU, as HSMs are only available at that tier (note that the
tenant_id can be read from your subscription using an
The next interesting resource is the functions app, where we specifically enable the managed identity (using the
identity block), as an identity is required when assigning a policy that will allow the app to access the vault:
And lastly, we add the
azurerm_key_vault_access_policy block that associates the functions app with the key vault and defines the permissions it will have. note that for this example, we will be using the keys mechanism of the key vault (
key_permissions block), and only allow the functions app to create, get the public and sign operations (
The Functions App
Now that we are done with the infrastructure, we can move to writing the functions app that will expose wallet related operations to the outside world, and on the other side, access the protected key vault.
For this article, we will be using C# and to create a new empty Azure Functions project, we can either use Visual Studio’s project template or the Azure Functions Core Tools. Either way, we once we have our empty project, we will add to HTTP trigger-based functions. The first will be the
CreateWallet function, which accesses the key vault and generates a
secp256k1 public and private key pair’ and generates an Ethereum address from the created public key:
And the second
Sign functions, which accepts a base64 encoded string of a hash payload (needs to be a 256-bit hash) and the wallet name to use for signing, and returns a base64 encoded string of the generated signature:
Note that both functions make use of an environment variable called
KEY_VAULT_URL, which was set in the Terraform script inside the
azurerm_function_app block to the URI of the key vault, removing the need of any manual configurations in the functions app.
Testing the Solution
To test the solution, we can use the Azure Portal, by navigating to the function we want to test and executing it with the parameters we want. To generate a base64 encoded hash that can be sent to the
Sign function, we can use:
- https://emn178.github.io/online-tools/sha3_256.html To generate a
hexstring of whatever value we want to sign.
- https://base64.guru/converter/encode/hex to convert the generated
hexstring, to a base64 encoded string.
This article covers the basics of how to create key pairs using Azure Key Vault that can be used on Ethereum based networks. In a production-grade environment, a solution for managing wallets will be much more restrictive and resilient, such as by adding authentication and authorization to the functions or expose operations for backing-up and restoring keys, which will provide an even better protection for the private keys and allow recovery of such keys in case of loss.