Simple Ethereum Wallets Management with Azure Key Vault

Itay Podhajcer
Dec 3, 2020 · 4 min read

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.

The Example

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:

Infrastructure Setup

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 azurerm_client_config block):

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 (create, get, sign):

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:

  1. https://emn178.github.io/online-tools/sha3_256.html To generate a hex string of whatever value we want to sign.
  2. https://base64.guru/converter/encode/hex to convert the generated hex string, to a base64 encoded string.

Conclusion

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.

Microsoft Azure

Any language.

Microsoft Azure

Any language. Any platform. Our team is focused on making the world more amazing for developers and IT operations communities with the best that Microsoft Azure can provide. If you want to contribute in this journey with us, contact us at medium@microsoft.com

Itay Podhajcer

Written by

Microsoft Azure MVP | Highly experienced software development & technology professional; consultant, architect & project manager

Microsoft Azure

Any language. Any platform. Our team is focused on making the world more amazing for developers and IT operations communities with the best that Microsoft Azure can provide. If you want to contribute in this journey with us, contact us at medium@microsoft.com