How to use Hyperledger Fabric SDK Go with Vault Transit engine

Richard Felkl
KompiTech
Published in
5 min readJul 29, 2019

This article focuses on replacing the default BCCSP (Blockchain Cryptographic Service Provider) security provider in Go SDK for Hyperledger Fabric with the Transit engine provided by HashiCorp’s Vault.

The security problem

You might be asking yourself the question, why is it beneficial to replace a built-in feature of the Go SDK? Each transaction sent to Hyperledger Fabric needs to be signed with a private key of the user who invokes the transaction. The Go SDK uses the BCCSP which does the signing for you. The BCCSP uses encryption keys and certificates loaded from the MSP directory on a local filesystem.

This is where the problem lies, a local filesystem. Usually the app which is connecting to blockchain using the Go SDK runs on some remote server. This means it’s necessary to store all user’s private keys on the filesystem of the remote server in plain text which is totally not recommended in production environments.

First of all, each user should have his private key securely stored on his location if storing it in plain text. Secondly, storing any private key in plain text is a huge security vulnerability because the plain text file may be read by an attacker or malicious code.

HashiCorp Vault

Vault from HashiCorp is a highly secured secret management system. It stores secrets such as passwords, certificates, API keys etc. in a strongly encrypted way. It also manages and enforces access to them based on trusted sources of application and user identity.

Another feature of Vault is the ability to encrypt or sign the data in transit and at rest across applications. The transit engine generates and stores private keys for users in an encrypted storage without the need to export them for usage. The encrypt and sign operations with the user’s private key are done based on the user’s authentication. That means the keys are protected the best possible way, and if the authentication information is compromised it’s easy to revoke it and grant access to the key with different authentication without changing the private key itself.

This feature is desired in systems like Hyperledger Fabric where changing the admin certificates in channel configuration can be a difficult and a time consuming process when there’s need to change the private keys which those certificates were issued for.

The design

The request originates on the client machine. It’s processed on the SDK server where it needs to be signed. The server uses the Vault to sign the request using the authentication from the original request. Vault returns the signature which is added to the final request that is sent to the Hyperledger Fabric network.

Hyperledger Fabric request flow using HashiCorp Vault.

Preparation

First, we need to have the Vault instance deployed and configured. This process is beyond the scope of this article. The next steps of this article can be achieved using Vault CLI or UI. If you prefer the CLI make sure you have it installed on your system and properly configured. For using UI navigate to http(s)://[VAULT_ADDR]:8200/ui and login. This article also assumes that you have the Go language installed and properly configured.

Let’s start with enabling the transit engine.

Using CLI:

vault secrets enable transit

Using UI:

  • On the secrets page click the Enable new engine button in the top right corner.
  • Select the Transit option and click Next .
  • Leave all parameters on default and click Enable engine .

Then, we need to create the user’s key in the Transit engine.

Using CLI:

vault write -f transit/keys/username

Using UI:

  • On the secrets page click on the transit/ secret.
  • Click the Create encryption key in the top right corner.
  • Fill in the name field i.e.username and click Create encryption key

We also need to create the CSR to be able to issue a certificate from CA. Since our private key is in Vault we can’t do it by Open SSL. I’ve made a simple program in Go to achieve this. So let’s install it.

go install github.com/richardfelkl/vault-tools-go/cmd/vault-tools 

Make sure you have your GOBIN environment variable in your path. You’ll then be able to execute the vault-tools command.

Let’s prepare the arguments for the CSR. In the example below there’s a JSON file with the minimum arguments you’ll need to place in the certificate. The common name should be the name of your user and Organization should be name of your organization.

{    "Organization": ["org1"],    "CommonName": "username"}

Now let’s execute vault-tools. It is able to read the Vault environment variables used for Vault CLI: VAULT_ADDR and VAULT_TOKEN . Make sure those variables are set or pass them in --address and --token parameters of the following command. The --names parameter is a path to JSON file created above. The --name parameter is the transit name.

vault-tools csr --name username --names ./names.json

This command will print the CSR in PEM format. Now you can use the CSR to issue the certificate from your CA. It could either be Fabric CA or another system you’re using. This process is beyond the scope of this article. The certificate is needed in the last step to make the example work.

Sample code

Let’s take a look at all the code you’ll need to make the integration work. Let’s assume following package structure of the Go code:

  • vault
  • identity
  • cryptosuite

We’re going to start with the code for the vault package. It will contain a Manager struct which is able to do sign and verify operations using the Vault Transit engine.

Now we need to define custom identity implementation that will use the Vault Transit engine to sign and verify transactions. It needs to be serializable into the Protobuf format. We also define a key which is type of core.Key .

The last package is cryptosuite . We need to define a custom cryptosuite implementation that is able to import public keys and verify signatures with them. We’ll make use of the VaultKey we defined in the identity package.

The last thing is the provider factory which manages the cryptosuite we created in previous step.

Now we have all necessary structures prepared and we can put it all together in a sample main application. Pay attention to variables with comments. Additional settings are needed.

Summary

And that’s it. It’s quite a lot of code to be defined for replacing the key components for signing, and that’s just a sample. There is still a lot of code missing to make it production ready, but it gives you a strong and secure mechanism for signing the Fabric transactions. The code for other SDKs like Node and Java may look similar.

--

--