Hyperledger Fabric Best Practices in Production- #1 Encrypting State Database With Chaincode

Due to the unbelievable popularity of blockchain technology, IBM’s Hyperledger Fabric project touching the sky, Not just because it is one of the blockchain frameworks. having some great unique features like permissioned architecture, Plug and Play components, Channel support for confidential Transactions, modularity, and scalability. due to all these facts, Hyperledger Fabric became revolutionary in this Blockchain Era. It has huge potential to change the industry and we are already seeing it right now. Hyperledger Fabric has progressed a lot over the past few months. Whether you are new to Hyperledger Fabric or have some experience and want to quickly get up to speed with the best Practices used for Production& Development of hyper ledger fabric, this post is for you. This is the series of articles and I’ll be adding more practices and tips to this series. For now, I want to publish my first pick “#1 Encrypting and Decrypting State Database With Nodejs Chaincode” today!

Google Image of Cat Doing Science

Big Picture

There are some cases when we will be dealing with sensitive data like storing credit card data, bank information, Biometric Data, Health Information, etc.. as a part of our business application in a distributed ledger. End-user always wanted to secure this confidential information even if the database is compromised. In quite a few applications, we’ll have a requirement to keep the data in our databases encrypted so that even if somebody gets into the database, they might not understand what the data is. however, In the blockchain, there are minute chances that the database is hacked. Although chances are less for hacking blockchain database, it is good practice to encrypt user data when storing in a blockchain database. Encryption is crucial in many applications. With the rise of popularity for Hyperledger Fabric these days, Let’s take a look at how we can encrypt data going into a database with our Nodejs Chaincode.

One thing you need to know before trying this on any production-grade application is that this will slow things down. There are two extra steps involved in this process — encrypting and decrypting the data. This will slow down your application a bit, and depending on the number of database reads and writes you have, this could have a significant impact on the performance of your application. Keep this in mind before you decide to encrypt everything in your database.

The Process

Before we can get to the encryption, First let me explain a bit about chaincode logic I’ve used here. What actually our chaincode does here is that simple user registration and login. Users will be registering on our application by providing username and password. These credentials will be stored as plain text in the database and whenever users logging in with the credentials, provided credentials will be validated with the credentials stored in the database. So we are going to add the encryption and decryption layer to these credentials. easy ?? let’s start.

For this example, I’m keeping this super simple and using an inbuilt crypto library for Nodejs. Depending on the application you’re working on, you can have a custom implementation of encryption and make it as complicated as you can.

Note: These encryption and decryption methods that I’m going to demonstrate in this article works under Nodejs Runtime v10.0.0.(Current runtime environment for Nodejs chaincode. — Hyperledger Fabric 1.4.3) However, in future releases, Nodejs runtime for chaincode will be moved to v12.13.0, So there would be a better approach we can encrypt and decrypt data. but, the technique would be the same. For that, I also added v12.13.0 compatible encryption and decryption methods in this demonstration repository.

1. Encryption:

The whole encryption utility for this example project is as follows:

function encrypt(data,password){   
  const cipher = crypto.createCipher('aes256', password);  
  let encrypted = cipher.update(data, 'utf8', 'hex');
  encrypted += cipher.final('hex');   
  return encrypted;

The method encrypt() will do exactly what you think it does. It’s just five lines of code using the built-in basic encryptor. encrypt() function will take two arguments — data and password. with the password, it will create encryption key based on a given algorithm aes256 and encrypt data with the encryption key and returns encrypted data. this is the whole idea behind encrypt() function. if you wanted to learn more about what exactly each line does, head over to here.

2. Decryption:

Here is the decryption utility for this example project:

function decrypt(cipherData,password)  {    
   const decipher = crypto.createDecipher('aes256', password);    
   let decrypted = decipher.update(cipherData, 'hex', 'utf8');
   decrypted += decipher.final('utf8');   
   return decrypted.toString();}

The method decrypt() will decrypt the encrypted data. decrypt() function will again take two arguments — Cipherdata and password. with the password, it will create a decryption key based on a given algorithm aes256 and decrypt cipherDatawith the decryption key and returns plain data. Learn More.

3. Implementation In Chaincode:

Note: The term password represents two different parameters. one is Signup/Login password for the business application and the other is encryption/decryption password to encrypt/decrypt data

We’ve seen our chaincode logic before. So, when a user submits his credentials(username and password), we’re supposed to encrypt them before putting them into the database. So our first task is to pass them to the encrypt() method. in addition to registration credentials(username, password), a user also needs to provide a strong encryption password. once , data is encrypted, encrypt() method will return encrypted data. Now we need to put this encrypted data on the database with a key of username. confused? have a look at signUp() function in code.

Similarly, when a user logs in, our chaincode needs to verify whether the username exists or not on the database and if it exists, it should check whether submitted password is correct or not. So, In order to check whether the password is correct or not, the data associated with the particular key(username) should be decrypted first, since it is encrypted. additionally, the user needs to provide same password as provided while encrypting the data. once decrypted, it will validate user login if provided login password matches the password associated with the particular key(username). here is the full code.

'use strict';
const shim = require('fabric-shim');
const util = require('util');
const crypto = require('crypto');
function encrypt(data,password){
const cipher = crypto.createCipher(‘aes256’, password);
let encrypted = cipher.update(data, ‘utf8’, ‘hex’);
encrypted += cipher.final(‘hex’);
return encrypted;
}function decrypt(cipherData,password) {
const decipher = crypto.createDecipher(‘aes256’, password);
let decrypted = decipher.update(cipherData, ‘hex’, ‘utf8’);
decrypted += decipher.final(‘utf8’);
return decrypted.toString();
}let Chaincode = class {async Init(stub) {
console.info(‘=========== Instantiated Validation Chaincode===========’);
return shim.success();
}async Invoke(stub) {
let ret = stub.getFunctionAndParameters();
console.info(ret);let method = this[ret.fcn];
if (!method) {
console.error(‘no function of name:’ + ret.fcn + ‘ found’);
throw new Error(‘Received unknown function ‘ + ret.fcn + ‘ invocation’);
try {
let payload = await method(stub, ret.params);
return shim.success(payload);
catch (err) {
return shim.error(err);
}async signUp(stub, args) {
if (args.length != 3) {
return Buffer.from(‘Incorrect number of arguments. Expecting 3’);
console.info(‘**Storing Credentials on Blockchain**’);const credentials = {userName:args[0],password:args[1]};
let data = JSON.stringify(credentials);
let cipher = encrypt(data,args[2]);await stub.putState(args[0], Buffer.from(JSON.stringify(cipher)));
console.info(‘*Signup Successfull..Your Username is ‘+args[0]);
return Buffer.from(‘Signup Successfull..Your Username is ‘+args[0]);
}async login(stub, args) {
if (args.length != 3) {
return Buffer.from(‘Incorrect number of arguments. Expecting 3’);

let userName=args[0];
let password=args[1];
let credentialsAsBytes = await stub.getState(args[0]);

if (!credentialsAsBytes || credentialsAsBytes.toString().length <= 0) {
return Buffer.from(‘Incorrect Username..!’);
let data= JSON.parse(credentialsAsBytes);
let decryptData= decrypt(data,args[2]);
let credentials= JSON.parse(decryptData);
if (password!=credentials.password) {
return Buffer.from(‘Incorrect Password..!’);

//Functions go here after signin
console.log(‘Login Successfull..✓’);
return Buffer.from(‘Login Successfull..’);


shim.start(new Chaincode());

Quick demo

git clone https://github.com/Salmandabbakuti/hlf-encryption.git
cd hlf-encryption
chmod 777 node-start.sh && chmod 777 go-start.sh
./node-start.sh #nodejs chaincode encryption model (credentials storing and validation logic) head over to fauxton UI http://localhost:5984/_utils
./go-start.sh #golang chaincode encryption model (tuna supplychain logic)

Plain Data in Database without Encryption.

Database With Added Encryption.

As you can see, the encryption and decryption magic is working.

If you’re interested in getting straight to the code, you can fork the complete project from here. If you have any doubts or suggestions for this, please feel free to leave comments below.

I’m going to publish a series of articles about “Hyperledger Fabric Best Practices In Production”. In the next article, I’m gonna explain how you can connect hyperledger explorer to your network with three simple steps.

So, are you guys interested? Follow me.

Happy Hyperledger Fabric🙌

Leave a Reply