Backend Development 22 min read

Encrypting Spring Boot Configuration with Jasypt – A Complete Guide

This article explains how to securely encrypt sensitive Spring Boot configuration properties such as database passwords using the Jasypt library, covering dependency setup, YAML configuration, encryption/decryption testing, custom encryptors, property detectors, resolvers, filters, and Maven plugin usage, all with practical code examples.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Encrypting Spring Boot Configuration with Jasypt – A Complete Guide

1. Overview

When using Spring Boot, sensitive information like database credentials is often stored in application.yml in plain text, which is insecure. Jasypt provides a simple way to encrypt these values and automatically decrypt them at runtime.

2. Simple Usage

2.1 Add Dependencies

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.4.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- web and test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- jdbc -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- jasypt encryption -->
    <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2.2 Configure application.yml

jasypt:
  encryptor:
    # encryption algorithm
    algorithm: PBEWITHHMACSHA512ANDAES_256
    # secret salt (should be supplied via env, CLI or system property)
    password: jaspyt_password

2.3 Encryption/Decryption Test

/**
 * @author HLH
 * @description Encryption/Decryption test
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class JasyptTest {

    @Autowired
    private StringEncryptor stringEncryptor;

    /**
     * Encryption test
     */
    @Test
    public void jasyptTest() {
        // encrypt
        System.out.println(stringEncryptor.encrypt("root")); // e.g. JSrINYe4IBotHndG...
        // decrypt
        System.out.println(stringEncryptor.decrypt("JSrINYe4IBotHndG...")); // root
    }

    /**
     * Manual test using Jasypt API directly
     */
    @Test
    public void test() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword("jaspyt_password");
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        System.out.println(encryptor.encrypt("root")); // encrypted value
    }
}

3. Using Encrypted Value in DataSource

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.10.31/mp
    username: root
    # wrap the encrypted password with ENC()
    password: ENC(R2H69h1aEgJ3EDPLXAVQ5CxZJWtl8EvqIJUtlATRt6om4w46/J+blu2JAvkR7Yvp)

4. Jasypt Configuration Details

All configuration properties are defined in JasyptEncryptorConfigurationProperties . The only required property is the secret jasypt.encryptor.password ; other properties have sensible defaults.

5. Custom Encryption Bean

@Bean("jasyptStringEncryptor")
public StringEncryptor jasyptStringEncryptor(Singleton
configProps) {
    PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
    JasyptEncryptorConfigurationProperties props = configProps.get();
    SimpleStringPBEConfig config = new SimpleStringPBEConfig();
    config.setPassword(props.getPassword());
    config.setAlgorithm(props.getAlgorithm());
    config.setKeyObtentionIterations(props.getKeyObtentionIterations());
    config.setPoolSize(props.getPoolSize());
    config.setProviderName(props.getProviderName());
    config.setSaltGeneratorClassName(props.getSaltGeneratorClassname());
    config.setIvGeneratorClassName(props.getIvGeneratorClassname());
    config.setStringOutputType(props.getStringOutputType());
    encryptor.setConfig(config);
    return encryptor;
}

6. Custom Property Detector

The detector decides whether a property value is encrypted and extracts the raw value.

@Bean(name = "encryptablePropertyDetector")
public EncryptablePropertyDetector encryptablePropertyDetector() {
    return new MyEncryptablePropertyDetector();
}

public class MyEncryptablePropertyDetector implements EncryptablePropertyDetector {
    @Override
    public boolean isEncrypted(String value) {
        return value != null && value.startsWith("ENC@"); // custom rule
    }
    @Override
    public String unwrapEncryptedValue(String value) {
        return value.substring("ENC@".length());
    }
}

7. Custom Prefix/Suffix

If you only need a different prefix/suffix, modify application.yml :

jasypt:
  encryptor:
    algorithm: PBEWITHHMACSHA512ANDAES_256
    password: jaspyt_password
    property:
      prefix: ENC(
      suffix: )

8. Custom Property Resolver

@Bean("encryptablePropertyResolver")
public EncryptablePropertyResolver encryptablePropertyResolver(StringEncryptor encryptor, EncryptablePropertyDetector detector) {
    return new MyEncryptablePropertyResolver(encryptor, detector);
}

public class MyEncryptablePropertyResolver implements EncryptablePropertyResolver {
    private final StringEncryptor encryptor;
    private final EncryptablePropertyDetector detector;
    public MyEncryptablePropertyResolver(StringEncryptor encryptor, EncryptablePropertyDetector detector) {
        this.encryptor = encryptor;
        this.detector = detector;
    }
    @Override
    public String resolvePropertyValue(String value) {
        return Optional.ofNullable(value)
            .filter(detector::isEncrypted)
            .map(v -> {
                try {
                    String raw = detector.unwrapEncryptedValue(v.trim());
                    return encryptor.decrypt(raw);
                } catch (EncryptionOperationNotPossibleException e) {
                    throw new DecryptionException("Unable to decrypt: " + value, e);
                }
            })
            .orElse(value);
    }
}

9. Custom Property Filter

The filter can exclude certain property sources or keys from decryption.

@Bean(name = "encryptablePropertyFilter")
public EncryptablePropertyFilter encryptablePropertyFilter(Singleton
configProps) {
    return new MyEncryptablePropertyFilter(configProps.get());
}

public class MyEncryptablePropertyFilter implements EncryptablePropertyFilter {
    private final JasyptEncryptorConfigurationProperties props;
    public MyEncryptablePropertyFilter(JasyptEncryptorConfigurationProperties props) { this.props = props; }
    @Override
    public boolean shouldInclude(PropertySource
source, String name) {
        List
exclude = props.getProperty().getFilter().getExcludeNames();
        List
include = props.getProperty().getFilter().getIncludeNames();
        if (CollectionUtils.isEmpty(include) && CollectionUtils.isEmpty(exclude)) {
            return true;
        }
        if (matches(source.getName(), exclude) || matches(name, exclude)) {
            return false;
        }
        return CollectionUtils.isEmpty(include) || matches(source.getName(), include) || matches(name, include);
    }
    private boolean matches(String value, List
patterns) {
        return value != null && !CollectionUtils.isEmpty(patterns) && patterns.stream().anyMatch(value::matches);
    }
}

10. Maven Plugin for Encryption/Decryption

10.1 Add Plugin

<build>
    <plugins>
        <!-- Jasypt Maven Plugin -->
        <plugin>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-maven-plugin</artifactId>
            <version>3.0.2</version>
        </plugin>
    </plugins>
</build>

10.2 Encrypt a value

mvn jasypt:encrypt-value \
    -Djasypt.encryptor.password="jaspyt_password" \
    -Djasypt.plugin.value="root" \
    -Djasypt.encryptor.algorithm="PBEWITHHMACSHA512ANDAES_256"

The command prints the encrypted string, which can be placed inside ENC() in application.yml .

10.3 Decrypt a value

mvn jasypt:decrypt-value \
    -Djasypt.encryptor.password="jaspyt_password" \
    -Djasypt.plugin.value="
" \
    -Djasypt.encryptor.algorithm="PBEWITHHMACSHA512ANDAES_256"

This returns the original plain text.

11. Mind Map

The article concludes with a visual mind map summarising the whole Jasypt integration process.

JavaconfigurationmavenSpring BootencryptionJasypt
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.