I tried the following few things(1 to 7) to resolve this exception, over which I've spent almost my entire day going insane. I consolidated my approaches & finally thought to pen it down into an answer to this exception. Hope it helps in some or the other way or gives you other possible ways through this answer at least.
Latest Jasypt maven dependency
1) pom.xml
<!-- JASYPT Maven Dependency -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- JASYPT Maven Plugin-->
<build>
<plugins>
<plugin>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-maven-plugin</artifactId>
<version>3.0.3</version>
</plugin>
</plugins>
</build>
2) @EnableEncryptableProperties
- Class level annotation
I added it to my configuration class, you can add it to your application class having main method too. I tried both & it worked fine but preferred to keep it in config class.
3) Changed my Encryption algo. to PBEWITHHMACSHA512ANDAES_256
earlier I was using PBEWithMD5AndDES
which works fine too. I preferred having AES-SHA due to few specifics instead of DES-MD5.
4) Added IvGenerator org.jasypt.iv.RandomIvGenerator
I added config.setIvGeneratorClassName( "org.jasypt.iv.RandomIvGenerator") which is the class to have an additional initialization vector key when encryption/decryption is performed.
5) Create a Unit Test(Spock/JUnit)
I also wrote a tiny spock unit test case which I honestly used for generating my encrypted keys for all my client secrets which also helped me test my unit logic for jasypt technique.
Spock
unit test is written in groovy
language which is almost as same as java. So if you don't know groovy just past this code in Java and change def to appropriate RHS side & change the method name too & add @Test
at method level & other required things for JUnit
.
void "Test the custom JASYPT encryptor functionality"() {
given: "OriginalPlainTextSecret and PrivateKey"
def OriginalPlainTextSecret = "SECRET_2B_ENCRYPTED_and_ENCODED_base64"
// JASYPT private key used for ciphering the actual secret. This key is not meant to be encrypted!
// It is intentionally kept same/common across all profiles/environments for simplicity.
def privateKey = environment.getRequiredProperty("jasypt.encryptor.privatekey")
def encryptor = new PooledPBEStringEncryptor()
def config = new SimpleStringPBEConfig()
config.setPassword(privateKey) // an additional private key required for encryption & decryption
config.setAlgorithm(CommonConstants.JASYPT_ENC_ALGO)
config.setKeyObtentionIterations(CommonConstants.OBTENTION_ITERATION)
config.setPoolSize(CommonConstants.POOL_SIZE)
config.setProviderName(CommonConstants.PROVIDER_NAME)
config.setSaltGeneratorClassName(CommonConstants.JASYPT_SALT_GENERATOR)
config.setIvGeneratorClassName(CommonConstants.JASYPT_INIT_VECTOR)
config.setStringOutputType(CommonConstants.BASE64_ENCODE)
encryptor.setConfig(config)
when: "When encryption & decryption is executed"
def encryptedData = encryptor.encrypt(OriginalPlainTextSecret)
def decryptedData = encryptor.decrypt(encryptedData)
then: "Validate the keys used"
println("ORIGINAL SECRET : " + OriginalPlainTextSecret)
println("ENCRYPTED SECRET : " + encryptedData)
println("DECRYPTED SECRET : " + decryptedData);
println("Is DECRYPTED SECRET identical as the ORIGINAL SECRET? :: " + OriginalPlainTextSecret.contentEquals(decryptedData))
}
6) Simplified the private key
(password - the extra key used for encryption)
My private key i.e the password(extra key) was unnecessarily too much complex and I made it less complex.
Following are few maven commands which help you understand this
7) Different maven commands for application.yaml
& application.properties
If you are using application.properties
mvn jasypt:encrypt -Djasypt.encryptor.password=UR_PRIVATE_KEY
If you are using application.yaml
- My file was placed under nested /config folder
mvn jasypt:encrypt -Djasypt.encryptor.password=UR_PRIVATE_KEY -Djasypt.plugin.path="file:src/main/resources/config/application.yaml"
Here, -Djasypt.encryptor.password=UR_PRIVATE_KEY is the additional jasypt encryptor's private key. DO NOT PLACE YOUR CLIENT SECRET/YOUR DATABASE PASSWORD HERE!
You need to place them inside your yaml/properties file as mentioned in below links.
- JASYPT blog link for readers
- YouTube link for impatient ones
- GitHub link - source code
- Jasypt online Encryption/Decryption tool
Following are different techniques just for learning new latest different techniques which I've thought of using in my microservice & which worked well for me but I feel were more of an overkill. But having some time, space, freedom and curiosity didn't hurt me. You can test it as well.
- Blog for AES-GSM Cipher Scheme & ChaCha20-Poly1305 Cipher Scheme
- AES-GSM Cipher Scheme GitHub
- ChaCha20-Poly1305 Cipher Scheme