In this tutorial, you will learn how to use Asymmetric Encryption(RSA key pair) to encrypt sensitive information in configuration properties served by Spring Cloud Config Server. Asymmetric Encryption is a stronger encryption type than symmetric encryption(shared key), but it requires a little bit more effort to set up because we need to generate an encryption key.
We use asymmetric or symmetric encryption to protect sensitive information(like passwords), which we put in configuration properties files stored in either Git or Native File System backend for Spring Cloud Config.
For symmetric encryption(shared key), please read this tutorial: Spring Cloud Config – Symmetric Encryption and Decryption.
For a step-by-step series of video lessons, please check this page: Spring Boot Microservices and Spring Cloud.
Add the Java Cryptography Extension
If you use Java 8, then for Spring Cloud to encrypt and decrypt properties, you will need to add the full-strength JCE to your JVM (it is not included by default). You can download the “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files” from Oracle and follow the installation instructions. Make sure you download JCE for your Java platform.
The installation process is very simple. You will need to copy the two downloaded jar files to a /lib/security folder in your JDK.
<java-home>/lib/security [Unix]
<java-home>\lib\security [Windows]
Note: Once you copy the JCE libraries, you will need to kill the running Java process and start it again. If that does not help, restart your computer.
Video tutorial
Generate Keystore for Asymmetric Encryption
To generate a Keystore file for Asymmetric Encryption, we will use keytool utility, which comes with JDK. Below is an example of using a keytool utility to generate a keystore file. The Keystore file will contain keys used in the encryption and decryption of information.
keytool -genkeypair -alias myKeyAlias -keyalg RSA \ -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \ -keypass keyPassword -keystore server.jks -storepass storePassword
where:
- myKeyAlias – Replace this value with an alias for your key,
- keyPassword – Changes the password under which the private/secret key identified by an alias is protected from old_keypass to new_keypass , which must be at least 6 characters.
- server.jks – A Keystore file name. You can come up with a different name,
- storePassword –
Changes the password used to protect the integrity of the Keystore contents. The new password is new_storepass, which must be at least 6 characters.
Migrate to PKCS12
Once you run the above keytool command, you might get the following warning message:
Warning: The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format...
If you get this message, follow the instructions mentioned in it and execute the command it suggests. For example:
keytool -importkeystore -srckeystore apiEncryptionKey.jks -destkeystore apiEncryptionKey.jks -deststoretype pkcs12
Video tutorial
Update Bootstrap.properties
Once the Keystore file is generated, update the bootstrap.properties file of your Spring Cloud Config. if the bootstrap.properties file does not exist, you will need to create it.
Add the following configuration to a bootstrap.properties file of your Spring Cloud Config.
encrypt.key-store.location=file://${user.home}/Desktop/dev/apiEncryptionKey.jks encrypt.key-store.password=1q2w3e4r encrypt.key-store.alias=apiEncryptionKey
Note: Please replace the values in the configuration properties above with those relevant to your Keystore file.
Encrypt Configuration Property
To encrypt configuration property value, start your Spring Cloud Config server and then send an HTTP POST request to a /encrypt URL endpoint. For example:
curl -X POST http://localhost:8012/encrypt -d mypassword
where:
- 8012 – is the port number on which my Spring Cloud Config server is running. In your case, this port number might be different.
- mypassword – is a string we want to encrypt.
The response, in my case, is an encrypted value:
AQBHVXPFFXXXh8Iot4ZprCohMMy/20QLlwtILo+E/556/LrvkaEs5cEn5VsR4RJhRShwYSx4+7tpGuZF5z72td/QJEPqpWBZmImjTInoPtr95KMemRTrVPAg924Abh3eLY2s0AMBf/MujJscmINjb6/9d/D1bPasEd3I6bziB/iFNpkwXGnAgxcVwUFpilRnEhiBKCt0Ap1VfNM4P0esufoAfgW8EKQlbExc74ZGL3e0KPN7IDIZpPM9vqDKNp1nj733oKrvUKTI/Uip/ab1v8EXV3nRg4IiNF+eC31TW09VpblnFmYb2xcZNV1rn640cYvEOC7FiOxaUGoakm4Zrw+5Ng2gX3UzXCjJqJCdHkLAVEH4g3wMlCnVrZnwvQ9k9uc=
Use Encrypted Property Value
To use the encrypted value of a configuration property, add the {cipher} prefix. For example:
mypassword={cipher}AQBHVXPFFXXXh8Iot4ZprCohMMy/20QLlwtILo+E/556/LrvkaEs5cEn5VsR4RJhRShwYSx4+7tpGuZF5z72td/QJEPqpWBZmImjTInoPtr95KMemRTrVPAg924Abh3eLY2s0AMBf/MujJscmINjb6/9d/D1bPasEd3I6bziB/iFNpkwXGnAgxcVwUFpilRnEhiBKCt0Ap1VfNM4P0esufoAfgW8EKQlbExc74ZGL3e0KPN7IDIZpPM9vqDKNp1nj733oKrvUKTI/Uip/ab1v8EXV3nRg4IiNF+eC31TW09VpblnFmYb2xcZNV1rn640cYvEOC7FiOxaUGoakm4Zrw+5Ng2gX3UzXCjJqJCdHkLAVEH4g3wMlCnVrZnwvQ9k9uc=
Note: If Spring Cloud Config cannot decrypt, it will add the invalid prefix to a property name and use n/a as a property value. For example, let’s assume we used an incorrect encryption key, and Spring Cloud Config could not decrypt the value of a mypassword property. In this case, you will see the following in a property source returned to a Microservice:
"invalid.mypassword": "<n/a>"
Decrypting Property Yourself
If you need to decrypt an encrypted value, send an HTTP POST request to a /decrypt URL endpoint of your Spring Cloud Config Server. For example:
curl -X POST http://localhost:8012/decrypt -d AQBHVXPFFXXXh8Iot4ZprCohMMy/20QLlwtILo+E/556/LrvkaEs5cEn5VsR4RJhRShwYSx4+7tpGuZF5z72td/QJEPqpWBZmImjTInoPtr95KMemRTrVPAg924Abh3eLY2s0AMBf/MujJscmINjb6/9d/D1bPasEd3I6bziB/iFNpkwXGnAgxcVwUFpilRnEhiBKCt0Ap1VfNM4P0esufoAfgW8EKQlbExc74ZGL3e0KPN7IDIZpPM9vqDKNp1nj733oKrvUKTI/Uip/ab1v8EXV3nRg4IiNF+eC31TW09VpblnFmYb2xcZNV1rn640cYvEOC7FiOxaUGoakm4Zrw+5Ng2gX3UzXCjJqJCdHkLAVEH4g3wMlCnVrZnwvQ9k9uc=
where:
- 8012 is the port number of which my Spring Cloud Config server is running. In your case, this port number might be different.
- c6462015030a9a5e2cd286ef2cc5935534f5004090443529c9752805a1187bcf is an encrypted value which we want to decrypt.
Video tutorial
I hope this tutorial was helpful to you.
If you are interested in learning more about building RESTful Microservices with Spring Boot and Spring Cloud and enjoy learning by watching a series of step-by-step video tutorials check out the following online video courses.