It is a good idea to use encryption for instance passwords, client ID, secrets and other information that you want to keep well … a secret.
WSO2 products have an inbuilt tool called secure vault that allows you to encrypt values. While the implementation is called “secure vault” and the underlying tool itself is called “cipher tool”. In this blog I’m going to show how you can enable cipher tool, and once you’ve done that how you can encrypt a password that you’re going to use in a data source configuration as part of a data service.
I am going to use the cipher tool on an out of the box copy off the enterprise integrator 6.6.0. “Out of the box” in this case means no changes no modifications, just unzip the zip file on the desktop so that you can easily follow the instructions on your own PC or server. The operating system that I am using is CentOS 7, hence use of the shell scripts that are typical for Linux. For Windows of course you use the BAT files in the same directory (the bin directory).
How does Ciphertool work? When you start cipher tool for the first time, it uses two files to determine what needs to be encrypted and to store the encrypted values. These files are “cipher-text.properties” and “cipher-tool.properties” that can be found in the sub directory [EI-HOME]/conf/security.
Cipher-tool.properties file contains the location of configuration files in which the passwords need to be encrypted. The format is quite simple and consists of three parts:
- The path / name of config file, e.g., conf/carbon.xml
- The xpath reference of config entry, e.g., //Server/Security/KeyStore/Password
- A flag that is either true or false which denotes if the value referenced by the xpath needs to be encrypted.
The documentation from WSO2 says that you should manually encrypt a values and put in the cipher-text file. That is of course possible, but there is another solution that I will show you later in this blog. Let’s first do it as WSO2 intended it.
To enable encryption, we need to go to the bin directory where the ciphertool tool script can be found.
The first time that you start it you need to give an extra parameter: -Dconfigure. This will take the default settings found in the two files and encrypt them.
Let’s look at these files in detail and subsequently the outcome of running the encryption task.
First the cipher-text file. What you will find here is the secret alias names and the corresponding plain text passwords that require encryption. The value is between the square brackets.
If we then look at the cipher-tool file, we can see that over there we will find the location of the file in which encrypted value needs to be stored.
Let’s start the ciphertool for the first time with the required parameter.
When we look at the carbon.xml file we indeed find that the original, plaintext value, has been replaced. We now see the following:
Let’s start the Enterprise Integrator. Because we also encrypted the keystore password, we need to enter it at start up, because to decrypt the passwords we need the password that is encrypted.
There is a solution, not a brilliant one however, if you do not want to enter the password and that is to put in a file in plaintext that will be read at start up. The name should be
password-tmp.It should be stored in the [EI-HOME] directory. If you want the file to remain in that location, you need to call it
password-persist. Note that for Windows, these files need to have the .txt suffix.
Now the Enterprise Integrator will start, and we can manually encrypt a value. Let us encrypt the password of a datasource configuration to MySQL. I am naming the encrypted value: Mysql.DB.Password. But first, start ciphertool again, this time without the aforementioned extra parameter. Note that you will have to enter the Keystore Password (wso2carbon by default) twice. In my setup the password for database connection is root (I know this is not secure, but this is of course a sample setup).
After entering the value for the second time, the encrypted value is shown in the terminal. Copy this value.
Open cipher-text and add the password to the file.
Now we can use this value in a data source configuration.
Of course, there are some steps required for set-up before we explore this configuration. I’m going to create a database in the table to try this out in my local Maria DB setup. I’m including the sql commands in this blog in case you want to try out. It is one of the samples that we use for training.
create database trainingdb; use trainingdb; CREATE TABLE books (number INT, title VARCHAR(50), writer VARCHAR(40), onloan CHAR(1)); INSERT INTO books (number, title, writer, onloan) VALUES(1,"A brief history of time", "S. Hawking", "N"); INSERT INTO books (number, title, writer, onloan) VALUES(2,"The Hitchhikers Guide to the Galaxy", "D. Adams", "N"); INSERT INTO books (number, title, writer, onloan) VALUES(3,"The Picture of Dorian Gray", "O. Wilde", "N"); select * from books;
We now have a database and a table with three records, so that part is now shorted out. Next we need to make the data source connection to the table. This however requires that we add a JDBC connector to the Enterprise Integrator. This goes into the lib directory and can be found directly under the enterprise integrator home directory ([EI-HOME]). You can download a jdbc connector from several places, for instance from this url. Please note that I’m using the MySQL connector rather then the MariaDB connector. This has its origin in the past where MariaDB required this due to an error in the JDBC connector. Copy the jar file (in the zip file) to the lib directory and (re)start the server. Note that this is because the lib directory is only read at start up.
Let the Enterprise Integrator start and access the URL of the Management UI.
Log in with admin / admin credentials and select Datasource on the Configure Tab.
Click on Add Datasource. Fill in the details. As you can see we do not have the option to use a secret alias because the datasource definition stores the value encrypted in the registry. So, an admin can create a datasource and developers can use that datasource in the GENERATION of Dataservices since that requires a predefined datasource.
Downloading the value shows the configuration. I have tidied it up a bit to show the xml markup.
But when you create a Data Service it is a different story. There you do need to enter a password. So, if you want your developers to use the Create Service, and not expose the password, you can use the mechanism we described before with the Mysql.DB.Password value.
I have added the select query to the Data service and as you can see, I am getting a response.
But is there another solution that you can take? Since the value needs to be added to the cipher-text file could you also create a dummy xml file in conf and use the startup configuration.
In other words, using the startup configuration with fields that we define ourselves in cipher-text and cipher-tool to generate the encrypted value?
I will setup a new EI and try out. I have created password.xml in the conf directory.
I have changed the cipher-text file to include the Mysql.DB.Password.
And cipher-tool to store the encrypted value.
Let us run the script. We get this message:
Protected Token [Mysql.DB.Password] is updated in /conf/password.xml successfully. When we look in the password.xml file this entry.
The cipher-text now shows the encrypted value.
A quick test with the Create Data service confirms that it works.