A Study on Blockchain Key Management Systems — Part 1

This article is a study on the different Key Management Systems that exist today and how they can be used as an Ethereum Wallet for key management.

Our end architecture would look something like this:

Blockchain KMS using different solutions

This will be a 3-part series that will address the different challenges of deploying a key management system using EthSigner (Consensys), Hashicorp Vault, Microsoft Azure Key Vault, and Infura and the steps that were taken to integrate each component.

The (Decentralised Identity) DID Service Endpoints will require the following functionality against an Ethereum public network:

  1. Deploy a Smart Contract on to the Rinkeby Testnet through Infura (and paying gas costs)

The challenge is to achieve the above without revealing your private key / mnemonic key by delegating all signing and transactions to the key management system. At no point is your key ever revealed to the outside world.

Part 1 of the series will talk about the steps that were taken to integrate EthSigner, Azure Key Vault, and Infura.

Part 2 of the series will talk about the steps that were taken to integrate EthSigner, Hashicorp Vault, and Infura.

Part 3 of the series will talk discuss integrating Hashicorp Vault, Eth Secrets engine and Infura.

What is a Key Management System?

Effective key management is core to any business large or small. Keys control and grant access to the most sensitive parts of your business, and if they fall in the wrong hands could prove disastrous from a financial, legal, regulatory compliance and reputation standpoint.

We hear about major data losses in the news all the time, from eBay to Equifax, impacting the lives of millions of people (https://www.csoonline.com/article/2130877/the-biggest-data-breaches-of-the-21st-century.html).

Physical Key Management System
Source: https://www.git-security.com/products/security/buildings-facilities-and-equipment

This is an example of a physical key management system that controls access to the KMS (password, key, and access card) as well as access to each individual key inside.

Administrators can control who has access to which key as well as view an audit log of keys that have been used, when, and for how long.

At any point, an administrator can revoke key access through the KMS.

Just like a physical key management system, an Encryption Key Management System handles secrets which grant access to your IT infrastructure (such as email servers, database servers, web applications, etc). The KMS allows an administrator to grant/revoke access to secrets, have an audit log of which applications have accessed the secrets, and to perform certain actions using the secret without ever revealing it (e.g. cryptographic signing of messages).

Without an effective key management system, what tends to happens is all the secrets are scattered throughout the different applications in your system (referred to as secrets sprawl). There is no one place to manage the passwords, so if there is a compromise to one of your systems, all your systems are impacted (e.g. if you have 50 applications accessing a shared database with a shared access key, comprising one application means that all other applications will need to be updated). This is referred to as the “blast radius” of the breach impact and defines how severe a cyber security breach is.

Source: https://medium.com/@jackalus/vault-kubernetes-auth-and-database-secrets-engine-6551d686a12

In this series of articles, we will look at two KMS (Azure Key Vault and Hashicorp Vault). The goal of the article is to talk about these platforms and integrate them with Ethereum (via Infura), EthSigner, and the vault themselves.

As to which is the better solution, I will leave that to the avid reader. Both solutions have their strengths and weaknesses and it really depends on your business use-case.

What is EthSigner and how does it work?

From EthSigner website: EthSigner is an open-source, client-agnostic, Ethereum transaction signer developed under the Apache 2.0 license and written in Java. EthSigner separates private key management from transaction validation by signing transactions using a private key that can be secured in a variety of cloud providers, or encrypted on a local disk.

In the solution architecture, I have used EthSigner as an abstracted wallet that handles the public key cryptography functions without having to manage the mnemonics/private keys. This has a huge advantage to enterprises who do not want to manage their private keys and instead want a secure solution to abstract the complexity. By combining EthSigner with a Key Management System, we can reduce the risk of losing a private key while still maintaining the flexibility of an Ethereum wallet to interact with the Blockchain.

EthSigner Transactions
EthSigner Transactions
Source: https://docs.ethsigner.pegasys.tech/en/latest/Concepts/Overview/

At a high level, EthSigner does the following:

  • Acts as a proxy between the Ethereum Blockchain, the KMS, and the DApp

The reason that EthSigner changes the eth_sendTransaction to eth_sendRawTransaction is because the private keys are not held in the Ethereum Client (in the case of Infura), hence the client would not be able to fulfil the transaction request. Instead, it delegates the signing of Ethereum transaction requests to the KMS and forwards them as raw transactions.

How do we integrate EthSigner, Azure Key Vault and Infura?

Integrating EthSigner with Azure Key Vault

The EthSigner website actually does a decent job of documenting how to integrate Azure Key Vault, just follow the tutorial found here. The challenge I found was what each of the properties were and how could I get access to the different configuration from Azure Key:

  • Key vault name

Follow the example from Microsoft (NodeJS Example) to configure a Key in the key vault and retrieve the above configuration.

How do I know it worked?

The only way I know to test that the configuration worked correctly was to start EthSigner and view the log messages. EthSigner will try to authenticate at the start of the application, and if an error occurs it will throw an exception explaining roughly what went wrong. The following picture shows an example of what you should see in your log files if you successfully configured EthSigner:

Log Message for EthSigner to indicate successful configuration of Key Vault

Configuring EthSigner with Infura

By default this doesn’t work. Regardless of what configuration I tried this just didn’t work because EthSigner needed a host name to resolve the IP Address for the “DOWNSTREAM_HTTP_HOST” property. It then used the same host name to forward requests to.

To use Infura, we need to configure https://<network>.infura.io/v3/YOUR-PROJECT-ID but if you used that as the downstream host EthSigner would fail to resolve the host IP Address and would not start up. If we remove this and only kept <network>.infura.io then Infura would reject the request with 403 Forbidden errors. It may have been possible to alter the request such that the DApp would send the authentication key to Infura, but then we now have DApp holding the authentication as well, which defeated the purpose of the whole EthSigner abstraction.

When I was digging in to the EthSigner source code, I realised there are a few key Java classes that interacted directly with Infura. These were the files that needed to be modified (TransactionTransmitter and PassThroughTransmitter):

By overriding the URL and adding the entire Infura URL (including the project id), we could successfully send transactions to Infura. I have forked and added the necessary changes as an argument to EthSigner (called downstream-http-request-args).

Here is an example GIST deploying a sample Ethereum Smart Contract onto the Rinkeby network using EthSigner (here is the etherscan). I am using ethersjs to manage the interaction with the Ethereum Client (in this case EthSigner started on http://localhost:8545).

This is a GIST showing how to deploy a smart contract using JsonRPCProvider and JsonSigner (note no private key is shared)

How do we ask EthSigner to digitally sign messages?

So this is all well and good and now we can deploy Smart Contracts and interact with the Blockchain through EthSigner, Infura, and Azure Key Vault; but what if I want to cryptographically sign a message? My key is in Azure Key Vault so there is no easy way to retrieve it to sign. What can I do?

You have a few options

  1. Manually manage Azure Key Vault by connecting using the same credentials as EthSigner and use the sign method (see here). Not ideal if you want to have EthSigner manage your connection to the blockchain …

For point 1, see below for sample source code to manually validate a signature.

For point 2, we will be modifying EthSigner source code to intercept eth_sign requests and route them directly to the KMS for signing. The reason you might choose point 2 is because EthSigner already interacts with and uses the KMS to sign transactions; extending it to sign messages means we are keeping all interaction logic of the blockchain and KMS within EthSigner.

Modify the EthSigner source code, intercept eth_sign requests and route only to the keystore (returning the results)

At this point I am assuming you have locked down your EthSigner instance, otherwise anyone can start signing and submitting transactions on your behalf.

Here is some sample code in which we use the JsonSigner returned from JsonRPCProvider to sign and validate a message using EthSigner:

ECDSA Signature using JsonRPCProvider and JsonSigner without exposing the public key

Additional Information IF you plan to use Azure Key Vault to resolve signatures

If you plan to use Azure Key Vault directly, a few things to remember when signing … I’m not going to bother to explain ECDSA because I don’t know enough about the maths to do a good enough job. Just a few things to consider when signing (this tripped me up when I was deep diving this):

  • ECDSA signatures have 3 components, the R, S and V values. (R,S) are the results of a ECDSA signature, while the V component is the recovery id (recid) representing one of the 4 possible points that the (R,S) points exist on the curve which matches the public key used to generate the signature (read this and be more confused). In any case, if you plan to use Azure Key Vault Directly you will need to know this information.

The algorithm for extracting a key from Azure Key Vault and validating a signature are as follows:

Source code sample to validate a signature from Azure Key Vault

What’s Next?

This is the first of a 3-part series

I wrote this because there was a lack of quality materials describing how to integrate these different wonderful technologies. As with most open-source tools the moment you stray from the path it was design for you run into a host of weird and wonderful problems. I hope this helps someone, and drop me a comment if you have some comments, suggestions, requests, etc.

Stay tuned, keep safe, and sign in next time! (pun totally intended).

Interested in the application of Blockchain technology in the betterment of civilisation

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store