Scenario

Suppose you are working on multiple Spring Boot/Spring Cloud projects that are using the spring cloud config server. You setup property encryption for the spring-cloud config. The encryption key is sored in your local profile as an environment variable ENCRYPT_KEY. Then, you switch to work on another spring-boot/spring-cloud project that does not use spring config server and have spring-cloud-context as a dependency. When you run this project you get the following exception stack trace:

Caused by: java.lang.NullPointerException: null
	at org.springframework.cloud.context.encrypt.EncryptorFactory.create(EncryptorFactory.java:54)
	at org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$RsaEncryptionConfiguration.textEncryptor(EncryptionBootstrapConfiguration.java:83)
	at org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$RsaEncryptionConfiguration$$EnhancerBySpringCGLIB$$c1a972bf.CGLIB$textEncryptor$0(<generated>)
	at org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$RsaEncryptionConfiguration$$EnhancerBySpringCGLIB$$c1a972bf$$FastClassBySpringCGLIB$$4d33eb7b.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
	at org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$RsaEncryptionConfiguration$$EnhancerBySpringCGLIB$$c1a972bf.textEncryptor(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 31 common frames omitted

Diagnostic

This is actually a spring bug! Another way to provide the encryption key to the config server is to use -Dencrypt.key=123 system property. If you do it this way everything is working fine. The problem only arises when the environment variable ENCRYPT_KEY is used. The root cause is in:

org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration.KeyCondition

This condition bean determines whether spring will initialize TextEncryptor class or not. When spring detects ENCRYPT_KEY environment variable the TextEncryptor class gets created. It uses KeyProperties to initialize encryptor. If -Dencrypt.key=123 is provided then KeyProperties is initialized with the key provided as a system property. If ENCRYPT_KEY environment variable is found KeyProperties are not initialized and the key member is null.

Solution

Remove ENCRYPT_KEY property from the environment prior to running spring boot application. The problem is fixed.

Leave a Reply

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

1 reply
  • My spouse and i have been contented that Emmanuel managed to carry out his homework through your precious recommendations he received while using the web page. It is now and again perplexing to just be giving for free thoughts that many many people might have been selling. Therefore we know we need you to thank for that. The entire illustrations you have made, the straightforward web site navigation, the friendships your site make it possible to promote – it’s got everything astonishing, and it is letting our son and us do think that content is thrilling, which is seriously mandatory. Thanks for all!