Spring Cloud Config – Asymmetric Encryption and Decryption

In this tutorial you will learn you 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 just 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 for example 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

For Spring Cloud to be able 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 simply. Basically 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 keystore file for Asymmetric Encryption we will use keytool utility which comes with JDK. Below is an example of how to use a keytool utility to generate a keystore file. The keystore file will contain keys which will be used in 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 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 then follow the instructions mentioned in the message 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 yet, 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 to the ones that are relevant to your keystore file.

Encrypt Configuration Property

To encrypt configuration property value, start you 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 a port number of 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 was not able to decrypt the it will add the invalid prefix to a property name and it will use n/a as a property value. For example, let’s assume we used an incorrect encryption key and Spring Cloud Config was not able to 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 HTTP POST request to a /decrypt URL endpoint of you 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 a 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 for you.

If you are interested to learn more about how to build RESTful Microservices with Spring boot and Spring Cloud and you enjoy learning by watching a series of step by step video tutorial, then have a look at the following list of online video courses.


Leave a Reply

Your email address will not be published. Required fields are marked *