Jasypt, “Java Simplified Encryption,” is a powerful encryption library for Java applications. It offers easy-to-use methods for encrypting and decrypting sensitive data, making it particularly beneficial for applications that handle confidential information like passwords, personal IDs, and API keys.
Sensitive data, such as passwords or personal IDs, must be securely encrypted to protect database access and ensure safe querying of personal information.
Key Benefits of Jasypt:
- Enhanced Data Security: Jasypt provides robust encryption for sensitive information, helping to secure data at rest in databases or during data transfer.
- Ease of Integration with Spring Boot: Jasypt is fully compatible with Spring Boot, allowing seamless integration for Java developers. This simplifies the encryption process and makes it accessible even for applications with complex data protection requirements.
- Support for Multiple Algorithms: Jasypt supports various encryption algorithms, allowing developers to choose the encryption method that best meets their security needs.
- Simplified Configuration: With Jasypt, there’s minimal setup. It automatically encrypts and decrypts properties, particularly useful for configuration files and sensitive properties like database credentials.
- Performance Optimization: Jasypt is designed for performance efficiency, ensuring that encryption processes don’t significantly impact application speed or user experience.
How to Implement Encryption and Decryption with Jasypt in Spring Boot 3
Jasypt provides encryption and decryption for both the one-way and two-way methods.
One-way encryption is encrypted only. The developer can’t decrypt the original text but can only verify that the input and encrypted text have the same value.
With two-way encryption, the developer can decrypt the original text with the secret key.
Setting Up Jasypt in a Spring Boot Project
For example, the responsible team will have two roles: the developer and the system team.
<!-- pom.xml -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>//ApplicationConfiguration.java
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableEncryptableProperties
public class ApplicationConfiguration {
@Bean
@ConfigurationProperties("jasypt.encryptor")
public SimpleStringPBEConfig jasypConfig() {
return new SimpleStringPBEConfig();
}
@Bean
public StringEncryptor jasyptEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setConfig(jasypConfig());
return encryptor;
}
}The system team will generate encrypted values and secret keys and then send only encrypted values to the developer team, who will place the values in the application properties in the Spring Boot project.
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=demo_text password=RvswK0aufhwchDg algorithm=PBEWithMD5AndTripleDES
JasyptPBEStringEncryptionCLI requires two parameter inputs and a password.
java -cp C:\jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=abc1234 password=RvswK0aufhwchDg algorithm=PBEWithMD5AndTripleDES ----ENVIRONMENT----------------- Runtime: Oracle Corporation Java HotSpot (TM) 64-Bit Server VM 17.0.6+9-LTS-190 ----ARGUMENTS------------------- input: abc1234 password: RvswK0aufhwchDg algorithm: PBEWithMD5AndTripleDES ----OUTPUT---------------------- tV/X5E0nxPAgqA/NIvAF9A==
JasyptStringDigestCLI requires one parameter input.
java -cp C:\jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptStringDigestCLI input=abc1234 algorithm=MD5 saltSizeBytes=8 ----ENVIRONMENT----------------- Runtime: Oracle Corporation Java HotSpot (TM) 64-Bit Server VM 17.0.6+9-LTS-190 ----ARGUMENTS------------------- input: abc1234 saltSizeBytes: 8 algorithm: MD5 ----OUTPUT---------------------- Gi1+4BvbhgrOK+oHNnAFbbTax22wDy8N
#abc1234 #application.properties demo.two.way.decrypt=ENC(tV/X5E0nxPAgqA/NIvAF9A==) demo.one.way.encrypt=Gi1+4BvbhgrOK+oHNnAFbbTax22wDy8N # =============================== # = JASYPT # =============================== Set these properties when starting the jar file. jasypt.encryptor.password=RvswK0aufhwchDg jasypt.encryptor.pool-size=4 jasypt.encryptor.bean=jasyptEncryptor jasypt.encryptor.algorithm=PBEWithMD5AndTripleDES jasypt.digester.algorithm=MD5 jasypt.encryptor.digester.salt.size.bytes=8
Step-by-Step Guide for Configuring Jasypt
- The developer team can get value from properties in two ways: the value decrypted inside the properties file or the value decrypted in the Java class.
- The system team only knows the value of Jasypt properties for the security protocol.
- When the system team deploys the application, follow the command line to set the properties of Jasypt.
java -jar -Djasypt.encryptor.password=RvswK0aufhwchDg \
-Djasypt.encryptor.pool-size=4 \
-Djasypt.encryptor.bean=jasyptEncryptor \
-Djasypt.encryptor.algorithm=PBEWithMD5AndTripleDES \
-Djasypt.digester.algorithm=MD5 \
-Djasypt.encryptor.digester.salt.size.bytes=8 \
application.jar4. Create a RESTful API for testing encryption and decryption.
@RestController
@RequiredArgsConstructor
public class Jasypt {
public final environment;
public final ApplicationConfiguration app;
@GetMapping(path = "/jasypt/compare", produces = "application/json")
public String getEncrypt(@PathParam("text") String text) {
StandardStringDigester digester = new StandardStringDigester();
digester.setAlgorithm("MD5"); //get value from properties "digester.algorithm" for security.
digester.setSaltSizeBytes(8); //get value from properties "digester.salt.size.bytes" for security.
String encryptedText = env.getProperty("demo.one.way.encrypt");
return digester.matches(text, encryptedText) ? "Match!" : "Not match!";
}
@GetMapping(path = "/jasypt/decrypt", produces = "application/json")
public ResponseEntity < String > getDecrypt(@PathParam("encryptText") String encryptText) {
System.out.println("encryptText = " + encryptText);
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setAlgorithm("PBEWithMD5AndTripleDES"); //get value from properties "jasypt.encryptor.algorithm" for security.
config.setPassword("RvswK0aufhwchDg"); //get value from properties "jasypt.encryptor.password" for security.
config.setPoolSize(4); //get value from properties "jasypt.encryptor.pool-size" for security.
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setConfig(config);
String original = null;
try {
original = encryptor.decrypt(encryptText);
System.out.println("original = " + original);
} catch (Exception ex) {
original = "Can't decrypt value because the value is not valid!";
}
return new ResponseEntity < > (original, HttpStatus.BAD_REQUEST);
}
@GetMapping(path = "/jasypt/property", produces = "application/json")
public String getProperty(@PathParam("key") String key) {
System.out.println("encryptText = " + key);
return env.getProperty(key);
}
}import jakarta.websocket.server.PathParam; import lombok.RequiredArgsConstructor; import org.jasypt.digest.StandardStringDigester; import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
Implementing Encryption and Decryption
1. Test the match value between the encrypted text and the input text.
curl http://localhost:8080/jasypt/compare?text=abc1234
StatusCode : 200
StatusDescription :
Content: Match!
RawContent : HTTP/1.1 200
Keep-Alive: timeout=60
Connection: keep-alive
Content-Length: 6
Content-Type: application/json
Date: Wed, 07 Feb 2024 08:37:06 GMT
Match!
Forms : {}
Headers : {[Keep-Alive, timeout=60], [Connection, keep-alive], [Content-Length, 6], [Content-Type,
application/json]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 6The result shows the value is “Match!” between the encrypted text and the input text.
curl http://localhost:8080/jasypt/compare?text=abc123456
StatusCode : 200
StatusDescription :
Content: Not a match!
RawContent : HTTP/1.1 200
Keep-Alive: timeout=60
Connection: keep-alive
Content-Length: 10
Content-Type: application/json
Date: Wed, 07 Feb 2024 08:39:07 GMT
Not match!
Forms : {}
Headers : {[Keep-Alive, timeout=60], [Connection, keep-alive], [Content-Length, 10], [Content-Type,
application/json]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 10The result shows the value is “Not a match!” between the encrypted text and the input text.
2. Test the decryption value of the encrypted text.
curl http://localhost:8080/jasypt/decrypt?encryptText=tV/X5E0nxPAgqA/NIvAF9A==
StatusCode : 200
StatusDescription :
Content : abc1234
RawContent : HTTP/1.1 200
Keep-Alive: timeout=60
Connection: keep-alive
Content-Length: 7
Content-Type: application/json
Date: Wed, 07 Feb 2024 08:41:07 GMT
abc1234
Forms : {}
Headers : {[Keep-Alive, timeout=60], [Connection, keep-alive], [Content-Length, 7], [Content-Type,
application/json]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 7The result shows the value of the original text “abc1234” after the decryption.
curl http://localhost:8080/jasypt/decrypt?encryptText=tV/X5E0nxPAgqA
curl: Can't decrypt value because the value is not valid!
At line:1 char:1
+ curl http://localhost:8080/jasypt/decrypt?encryptText=tV/X5E0nxPAgqA
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
eption
+ FullyQualifiedErrorId: WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommandThe error result shows “Can’t decrypt value because the value is invalid!”.
3. The test gets a decrypted value from the application.properties file.
curl http://localhost:8080/jasypt/property?key=demo.two.way.decrypt
StatusCode : 200
StatusDescription :
Content : abc1234
RawContent : HTTP/1.1 200
Keep-Alive: timeout=60
Connection: keep-alive
Content-Length: 7
Content-Type: application/json
Date: Wed, 07 Feb 2024 08:51:22 GMT
abc1234
Forms : {}
Headers : {[Keep-Alive, timeout=60], [Connection, keep-alive], [Content-Length, 7], [Content-Type,
application/json]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 7The result shows the value of the decrypted text “abc1234”. This value is decrypted in a properties file.
Jasypt library is out of maintenance the latest version Jasypt 1.9.3 RELEASED! (May 25th, 2019) and jasypt-spring-boot-starter 3.0.5 (Dec 15, 2022).
Finally
This is the basic concept of the encryption and decryption processes.
The developer should learn and understand the concepts of encryption and decryption processes. In the future, the developer can use this concept to adapt to any similar library and apply it to the project.
This article was originally published on Medium.





