Hyperledger Fabric is one of the most popular blockchain development frameworks. It has unique positioning and some distinctive features, such as licensing architecture, pluggable components, channels supporting private transactions, modularity and scalability, so it is suitable for the development of enterprise alliance chain applications. In this article, we will show how to use chain code to encrypt / decrypt sensitive data stored on the Hyperledger Fabric blockchain.
1. Application background of Hyperledger Fabric chain code encryption / decryption
In the enterprise environment, sometimes we need to deal with some sensitive data, such as saving credit card data, bank information, biometric data, health information and so on. These sensitive data are part of our business application based on distributed ledgers, and end users usually hope to ensure the security of these private information even when the data is penetrated.
In some traditional applications, we will encrypt the data in the database, so that even if someone sneaks into the database, they can't understand the real meaning of the data. Similarly, encrypting user data in blockchain database is also an effective means to protect privacy. Now let's see how to use NodeJS chain code to encrypt the data to be written to the blockchain database.
Before we start the follow-up implementation, we need to point out that the introduction of additional encryption and decryption links will slow down the application processing speed in the production environment. The larger the amount of data to be encrypted / decrypted, the greater the impact on the application performance.
2. Processing flow of Hyperledger Fabric chain code encryption / decryption
Before we start encryption, let's explain the logic of the chain code to be used. Example chain code is a simple implementation of user registration and login. The user needs to provide a user name and password for registration, and these identity information will be saved in the database in clear text. When the user logs in, the identity information saved in the database will be used for authentication. So we will add Encryption / decryption layer.
In this example, I'll try to keep the code simple, using the crypto library built into nodejs. Depending on the application, you can also use a custom encryption implementation.
The encryption method 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 encrypt() method uses aes256 algorithm to encrypt the specified data. It has two parameters:
- Data: data to encrypt
- Password: encrypt password
The decryption method is as follows:
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 decrypt() method uses aes256 algorithm and the incoming encryption password to decrypt the incoming encrypted data.
3. Implementation code of Hyperledger Fabric chain code encryption / decryption
We introduced the logic of user registration / login chain code before. When a user registers, he / she submits his / her user name and login password, so we need to encrypt the user's identity data before storing it in the Hyperledger Fabric blockchain.
async signUp(stub, args) { if (args.length != 3) { return Buffer.from('Incorrect number of arguments. Expecting 3'); }else{ 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]); } }
Similarly, when logging in, the chain code needs to verify whether the user name exists in the Hyperledger Fabric's chain database and check whether the password is correct. Therefore, before checking the identity information, you need to first decrypt the data on the Hyperledger Fabric chain:
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..!'); } else{ 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..'); } } }
Finally, we implement the routing distribution of user registration / login chain code:
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) { console.log(err); return shim.error(err); } }
The complete Hyperledger Fabric code can be found in the Here Download.
Original link: Hyperledger Fabric best practice - encrypting / decrypting data on chain with chain code - huizhi.com