Exploring Fabric-CA: Registration and Enrollment

KC Tam
8 min readSep 18, 2019

Overview

Hyperledger Fabric is a permissioned blockchain platform. One must be identified and permissioned before one can interact with the fabric network. The identity is implemented with Digital Certificates and therefore a Certificate Authority (CA) is needed to handle the certificate management.

While Hyperledger Fabric allows use of third-party CA as it may be required in Enterprise world, it also comes with a handy Fabric-CA serving as a CA for a fabric network. As most application examples in fabric samples are using Fabric-CA (either using Basic Network and First Network), we will look into Fabric-CA, in particular in its role of user registration and enrollment.

In this article we use Fabcar application deployed on First Network. This sample application contains chaincode and client applications using the Software Development Kit (SDK). In particular the two codes enrollAdmin.js and registerUser.js have implemented the enrollment and registration on Fabric-CA.

To make the process more demonstrable, I have reworked on the codes to make things clearer. In parallel, we will take a look on the Fabric-CA database, to have a better understanding what happens in Fabric-CA side during enrollment and user registration.

Setup

We need a fabric node to perform the demonstration. It have all the prerequisite and Hyperledger Fabric related software. If you have not yet such a fabric node, you can refer to this article to create one.

Once you have this node, you can run the fabric-samples/fabcar/startFabric.sh script to bring up the Fabcar.

cd fabric-samples/fabcar
./startFabric.sh

This script brings up the First Network, with CA being brought up for each organization. I have another article covering the detail about the Fabcar. In this work, our focus is on the Fabric-CA for Org1.

We are using Javascript codes provided in the Fabcar application. In particular we look into enrollAdmin.js and registerUser.js. as both are using SDK to interact with the Fabric-CA and fabric network.

This is how the First Network looks like, and how the given client application codes interact with the fabric network. Again we are focusing on the ca_peerOrg1 and the two codes for enrollment and registration (enrollAdmin.js and registerUser.js) in this article.

Fabcar deployed in First Network, and client applications access the fabric network using SDK.

Codes for Enrollment and Registration

Enrollment and Registration

These are the two processes we interact with Fabric-CA. Enrollment is the process by which a user requests and obtains a digital certificate from a given CA. Registration is usually done by a Registrar, telling a CA to issue the digital certificate.

There are various ways to issue the digital certificate to a user. For our interest and based on the Fabcar scripts, the process is like this

  1. An admin (registrar) is enrolled to the CA. Then the admin receives the signing key and certificate for this admin. They are stored in wallet/admin directory.
  2. The admin then registers user1 into the CA with proper information. The CA returns with a secret.
  3. This secret is then used to enroll user1 to the CA. The result is the signing key and certificate for user1. They are stored in wallet/user1 directory, and will be used to perform chaincode interaction (query and invoke) later.

The scripts enrollAdmin.js performs step 1, while registerUser.js performs both step 2 and 3.

The codes provided in fabcar applications.

Rework the Code

The enrollAdmin.js is kept unchanged. It simply uses the default bootstrap administrator (admin:adminpw), which is preset in the docker-compose-ca.yaml inside fabric-samples/first-network/. The result is the signing key and certificate for that admin (registrar) kept in wallet/admin directory.

For better illustration, the registerUser.js is broken into two: regUser.js and enrollUser.js. The reason behind,

  • We can observe the difference between registration and enrollment of a user.
  • We can show that this two steps in fact should be done by different parties: registration is done by a registrar (admin), while enrollment of a user is done by the user with the secret given. This is important as only no one except the user can receive the signing key, which should be kept privacy even the registrar should not know.
  • We can take out the hardcoded portion inside the code (like user1) and make them as argument. This makes the code more ready to use in other cases.

Here is how it looks like after the code is rewritten.

Code rewritten to show the three steps clearer.

Register a User: regUser.js

regUser.js requires an argument, the enrollment ID. The result is a secret, which will be used later for user enrollment. Note that regUser.js requires existence of admin wallet.

node regUser.js <enrollmentID>

The code is largely copied from the original registerUser.js with proper modification.

Enroll a User: enrollUser.js

enrollUser.js requires two arguments, the enrollment ID and the secret obtained in registration. The result is a wallet created in the designated in the wallet directory. Note that enrollUser.js does not require existence of admin wallet. It is supposed to be executed by user herself.

node enrollUser.js <enrollmentID> <secret>

The code makes reference to the original enrollAdmin.js with proper modification.

Demonstration

We will show how to run these three scripts to register and enroll user1 for Fabcar application.

Step 1: Run fabcar/startFabric.sh and make sure wallet is empty.

cd fabric-samples/fabcar
./startFabric.sh
cd javascript
rm -rf wallet
Remove everything inside wallet directory

Step 2: Install the required modules

npm install

Step 3: Install sqlite3 in CA of org1

As we are going to inspect the database in CA, install the sqlite3 to perform the inspection.

Open another terminal.

docker exec -it ca_peerOrg1 bash

Install the sqlite3 in ca_peerOrg1.

apt-get update
apt-get install sqlite3

The Fabric-CA database is kept in /etc/hyperledger/fabric-ca-server/fabric-ca-server.db. Now we can inspect the database.

cd /etc/hyperledger/fabric-ca-server
sqlite3 fabric-ca-server.db

Now we are in the command line shell of sqlite.

sqlite> .tables

Among the tables, we are interested in the users table and certificates table. To see the content in these tables.

sqlite> select * from users;
sqlite> select * from certificates;

We see a user admin is already in the database. This is done when the CA is started (see the command in the docker-compose file with -b admin:adminpw). And this bootstrap admin has almost all roles set. There is no certificate generated yet (no enrollment is done yet).

Now we are ready to perform the first enrollment: the enrollment of registrar using this admin.

Step 4: Enroll the Admin (Registrar)

We first enroll the admin to obtain the signing key and certificate for the admin, stored in wallet/admin.

node enrollAdmin.js

If we now check again the users table in CA.

We can see a field in admin is changed from 0 to 1. It is the state, meaning that a certificate is issued. We now can see a certificate is issued.

If we quickly compare this with what is stored in wallet/admin, we see this is the actual certificate for admin.

Step 5: Register user1 into CA

Now we run regUser.js to register user1 into the CA.

node regUser.js user1

We now receive the secret MDfRiAUccsna. This is needed in user enrollment in next step. We see no new wallet for user1 yet.

If we inspect the CA database it is much clearer what has happened. We see user1 is added to users table, while no new certificate for user1 is yet created (not enrolled yet). The attributes of user1 match what is coded in regUser.js. Also the state is 0 for user1, meaning that the certificate is not issued yet.

Step 5: Enroll user1 and obtain the signing key and certificate

Run enrollUser.js to enrol user1 to CA with the secret.

node enrollUser.js user1 MDfRiAUccsna

We see user1 is now in the wallet. We also see a new certificate created for user1 in the CA database.

And the state is changed to 1 after the certificate is issued (after user1 is enrolled).

Step 6: Finally we can use user1 to run the Fabcar scripts (query.js) and see if user1 can perform query. Note that in query.js user1 is hardcoded.

node query.js

The user user1 can perform the chaincode query as expected.

BONUS: Simulating loss of user1 wallet

Let’s remove user1 wallet to simulate a loss.

rm -r wallet/user1

We first will try to enroll user1 again with the same of secret.

node enrollUser.js user1 MDfRiAUccsna

The enrollment fails. If we take a look on the log of CA we know why this happens.

docker logs ca_peerOrg1

Now we do a trick on the Fabric-CA database. First we remove the user1 in certificates table, and then we change the state of user1 from 1 to 0 in users table.

sqlite> delete from certificates where id='user1';
sqlite> update users set state=0 where id='user1';

After this trick, we can enroll user1 again, with the same secret.

This new user1 wallet can be used again for chaincode query.

Note: this is not a formal way as we should avoid modifying the database directly. Nevertheless this can be a way in case it is needed.

Step 7: Clean Up

To quit the CA container

sqlite> .exit
# exit

To clean up the Fabcar and First-Network

cd fabric-samples/first-network
./byfn.sh down
docker rm $(docker ps -aq)
docker rmi $(docker images dev-* -q)

Summary

This article focused on Fabric-CA, showing how enrollment and registration are done using the SDK. With the code reworked, we see the process in a step-by-step manner. By studying the information stored in Fabric-CA database, we learned on how Fabric-CA handles the user registration and enrollment. We also performed a small trick to re-issue signing key and certificate for a user in case the wallet is lost.

--

--