Skip to content

ulisesbocchio/jasypt-spring-boot

Repository files navigation

jasypt-spring-boot

Jasyptintegration for Spring boot 2.x and 3.0.0

Build Status Gitter Maven Central

Code Climate Codacy Badge GitHub release Github All Releases MIT License volkswagen status

Paypal

"Buy Me A Coffee"

Jasypt Spring Boot provides Encryption support for property sources in Spring Boot Applications.
There are 3 ways to integratejasypt-spring-bootin your project:

  • Simply adding the starter jarjasypt-spring-boot-starterto your classpath if using@SpringBootApplicationor@EnableAutoConfigurationwill enable encryptable properties across the entire Spring Environment
  • Addingjasypt-spring-bootto your classpath and adding@EnableEncryptablePropertiesto your main Configuration class to enable encryptable properties across the entire Spring Environment
  • Addingjasypt-spring-bootto your classpath and declaring individual encryptable property sources with@EncrytablePropertySource

What's new?

What to do First?

Use one of the following 3 methods (briefly explained above):

  1. Simply add the starter jar dependency to your project if your Spring Boot application uses@SpringBootApplicationor@EnableAutoConfigurationand encryptable properties will be enabled across the entire Spring Environment (This means any system property, environment property, command line argument, application.properties, application-*.properties, yaml properties, and any other property sources can contain encrypted properties):

    <dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.5</version>
    </dependency>
  2. IF you don't use@SpringBootApplicationor@EnableAutoConfigurationAuto Configuration annotations then add this dependency to your project:

    <dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot</artifactId>
    <version>3.0.5</version>
    </dependency>

    And then add@EnableEncryptablePropertiesto you Configuration class. For instance:

    @Configuration
    @EnableEncryptableProperties
    publicclassMyApplication{
    ...
    }

And encryptable properties will be enabled across the entire Spring Environment (This means any system property, environment property, command line argument, application.properties, yaml properties, and any other custom property sources can contain encrypted properties)

  1. IF you don't use@SpringBootApplicationor@EnableAutoConfigurationAuto Configuration annotations and you don't want to enable encryptable properties across the entire Spring Environment, there's a third option. First add the following dependency to your project:

    <dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot</artifactId>
    <version>3.0.5</version>
    </dependency>

    And then add as many@EncryptablePropertySourceannotations as you want in your Configuration files. Just like you do with Spring's@PropertySourceannotation. For instance:

    @Configuration
    @EncryptablePropertySource(name="EncryptedProperties",value="classpath:encrypted.properties")
    publicclassMyApplication{
    ...
    }

Conveniently, there's also a@EncryptablePropertySourcesannotation that one could use to group annotations of type@EncryptablePropertySourcelike this:

@Configuration
@EncryptablePropertySources({@EncryptablePropertySource("classpath:encrypted.properties"),
@EncryptablePropertySource("classpath:encrypted2.properties")})
publicclassMyApplication{
...
}

Also, note that as of version 1.8,@EncryptablePropertySourcesupports YAML files

Custom Environment

As of version1.71.15, a 4th method of enabling encryptable properties exists for some special cases. A customConfigurableEnvironmentclass is provided:EncryptableEnvironmentStandardEncryptableEnvironmentandStandardEncryptableServletEnvironmentthat can be used withSpringApplicationBuilderto define the custom environment this way:

newSpringApplicationBuilder()
.environment(newStandardEncryptableEnvironment())
.sources(YourApplicationClass.class).run(args);

This method would only require using a dependency forjasypt-spring-boot.No starter jar dependency is required. This method is useful for early access of encrypted properties on bootstrap. While not required in most scenarios could be useful when customizing Spring Boot's init behavior or integrating with certain capabilities that are configured very early, such as Logging configuration. For a concrete example, this method of enabling encryptable properties is the only one that works with Spring Properties replacement inlogback-spring.xmlfiles, using thespringPropertytag. For instance:

<springPropertyname="user"source="db.user"/>
<springPropertyname="password"source="db.password"/>
<appendername="db"class="ch.qos.logback.classic.db.DBAppender">
<connectionSource
class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>org.postgresql.Driver</driverClass>
<url>jdbc:postgresql://localhost:5432/simple</url>
<user>${user}</user>
<password>${password}</password>
</connectionSource>
</appender>

This mechanism could be used for instance (as shown) to initialize Database Logging Appender that require sensitive credentials to be passed. Alternatively, if a customStringEncryptoris needed to be provided, a static builder method is providedStandardEncryptableEnvironment#builderfor customization (other customizations are possible):

StandardEncryptableEnvironment
.builder()
.encryptor(newMyEncryptor())
.build()

How everything Works?

This will trigger some configuration to be loaded that basically does 2 things:

  1. It registers a Spring post processor that decorates all PropertySource objects contained in the Spring Environment so they are "encryption aware" and detect when properties are encrypted following jasypt's property convention.
  2. It defines a defaultStringEncryptorthat can be configured through regular properties, system properties, or command line arguments.

Where do I put my encrypted properties?

When using METHODS 1 and 2 you can define encrypted properties in any of the PropertySource contained in the Environment. For instance, using the @PropertySource annotation:

@SpringBootApplication
@EnableEncryptableProperties
@PropertySource(name="EncryptedProperties",value="classpath:encrypted.properties")
publicclassMyApplication{
...
}

And your encrypted.properties file would look something like this:

secret.property=ENC(nrmZtkF7T0kjG/VodDvBw93Ct8EgjCA+)

Now when you doenvironment.getProperty( "secret.property" )or use@Value( "${secret.property}" )what you get is the decrypted version ofsecret.property.
When using METHOD 3 (@EncryptablePropertySource) then you can access the encrypted properties the same way, the only difference is that you must put the properties in the resource that was declared within the@EncryptablePropertySourceannotation so that the properties can be decrypted properly.

Password-based Encryption Configuration

Jasypt uses anStringEncryptorto decrypt properties. For all 3 methods, if no customStringEncryptor(see theCustom Encryptorsection for details) is found in the Spring Context, one is created automatically that can be configured through the following properties (System, properties file, command line arguments, environment variable, etc.):

KeyRequiredDefault Value
jasypt.encryptor.passwordTrue-
jasypt.encryptor.algorithmFalsePBEWITHHMACSHA512ANDAES_256
jasypt.encryptor.key-obtention-iterationsFalse1000
jasypt.encryptor.pool-sizeFalse1
jasypt.encryptor.provider-nameFalseSunJCE
jasypt.encryptor.provider-class-nameFalsenull
jasypt.encryptor.salt-generator-classnameFalseorg.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.iv-generator-classnameFalseorg.jasypt.iv.RandomIvGenerator
jasypt.encryptor.string-output-typeFalsebase64
jasypt.encryptor.proxy-property-sourcesFalsefalse
jasypt.encryptor.skip-property-sourcesFalseempty list

The only property required is the encryption password, the rest could be left to use default values. While all this properties could be declared in a properties file, the encryptor password should not be stored in a property file, it should rather be passed as system property, command line argument, or environment variable and as far as its name isjasypt.encryptor.passwordit'll work.

The last property,jasypt.encryptor.proxyPropertySourcesis used to indicatejasyp-spring-boothow property values are going to be intercepted for decryption. The default value,falseuses custom wrapper implementations ofPropertySource,EnumerablePropertySource,andMapPropertySource.Whentrueis specified for this property, the interception mechanism will use CGLib proxies on each specificPropertySourceimplementation. This may be useful on some scenarios where the type of the originalPropertySourcemust be preserved.

Use you own Custom Encryptor

For custom configuration of the encryptor and the source of the encryptor password you can always define your own StringEncryptor bean in your Spring Context, and the default encryptor will be ignored. For instance:

@Bean("jasyptStringEncryptor")
publicStringEncryptorstringEncryptor() {
PooledPBEStringEncryptorencryptor=newPooledPBEStringEncryptor();
SimpleStringPBEConfigconfig=newSimpleStringPBEConfig();
config.setPassword("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);
returnencryptor;
}

Notice that the bean name is required, asjasypt-spring-bootdetects custom String Encyptors by name as of version1.5.The default bean name is:

jasyptStringEncryptor

But one can also override this by defining property:

jasypt.encryptor.bean

So for instance, if you definejasypt.encryptor.bean=encryptorBeanthen you would define your custom encryptor with that name:

@Bean("encryptorBean")
publicStringEncryptorstringEncryptor() {
...
}

Custom Property Detector, Prefix, Suffix and/or Resolver

As ofjasypt-spring-boot-1.10there are new extensions points.EncryptablePropertySourcenow usesEncryptablePropertyResolverto resolve all properties:

publicinterfaceEncryptablePropertyResolver{
StringresolvePropertyValue(Stringvalue);
}

Implementations of this interface are responsible of bothdetectinganddecryptingproperties. The default implementation,DefaultPropertyResolveruses the before mentioned StringEncryptorand a newEncryptablePropertyDetector.

Provide a CustomEncryptablePropertyDetector

You can override the default implementation by providing a Bean of typeEncryptablePropertyDetectorwith nameencryptablePropertyDetectoror if you wanna provide your own bean name, override propertyjasypt.encryptor.property.detector-beanand specify the name you wanna give the bean. When providing this, you'll be responsible for detecting encrypted properties. Example:

privatestaticclassMyEncryptablePropertyDetectorimplementsEncryptablePropertyDetector{
@Override
publicbooleanisEncrypted(Stringvalue) {
if(value!=null) {
returnvalue.startsWith("ENC@");
}
returnfalse;
}

@Override
publicStringunwrapEncryptedValue(Stringvalue) {
returnvalue.substring("ENC@".length());
}
}
@Bean(name="encryptablePropertyDetector")
publicEncryptablePropertyDetectorencryptablePropertyDetector() {
returnnewMyEncryptablePropertyDetector();
}

Provide a Custom Encrypted Propertyprefixandsuffix

If all you want to do is to have different prefix/suffix for encrypted properties, you can keep using all the default implementations and just override the following properties inapplication.properties(orapplication.yml):

jasypt:
encryptor:
property:
prefix:"ENC@["
suffix:"]"

Provide a CustomEncryptablePropertyResolver

You can override the default implementation by providing a Bean of typeEncryptablePropertyResolverwith nameencryptablePropertyResolveror if you wanna provide your own bean name, override propertyjasypt.encryptor.property.resolver-beanand specify the name you wanna give the bean. When providing this, you'll be responsible for detecting and decrypting encrypted properties. Example:

classMyEncryptablePropertyResolverimplementsEncryptablePropertyResolver{


privatefinalPooledPBEStringEncryptorencryptor;

publicMyEncryptablePropertyResolver(char[]password) {
this.encryptor=newPooledPBEStringEncryptor();
SimpleStringPBEConfigconfig=newSimpleStringPBEConfig();
config.setPasswordCharArray(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);
}

@Override
publicStringresolvePropertyValue(Stringvalue) {
if(value!=null&&value.startsWith("{cipher}")) {
returnencryptor.decrypt(value.substring("{cipher}".length()));
}
returnvalue;
}
}
@Bean(name="encryptablePropertyResolver")
EncryptablePropertyResolverencryptablePropertyResolver(@Value("${jasypt.encryptor.password}")Stringpassword) {
returnnewMyEncryptablePropertyResolver(password.toCharArray());
}

Notice that by overridingEncryptablePropertyResolver,any other configuration or overrides you may have for prefixes, suffixes, EncryptablePropertyDetectorandStringEncryptorwill stop working since the Default resolver is what uses them. You'd have to wire all that stuff yourself. Fortunately, you don't have to override this bean in most cases, the previous options should suffice.

But as you can see in the implementation, the detection and decryption of the encrypted properties are internal toMyEncryptablePropertyResolver

Using Filters

jasypt-spring-boot:2.1.0introduces a new feature to specify property filters. The filter is part of theEncryptablePropertyResolverAPI and allows you to determine which properties or property sources to contemplate for decryption. This is, before even examining the actual property value to search for, or try to, decrypt it. For instance, by default, all properties which name start withjasypt.encryptor are excluded from examination. This is to avoid circular dependencies at load time when the library beans are configured.

DefaultPropertyFilter properties

By default, theDefaultPropertyResolverusesDefaultPropertyFilter,which allows you to specify the following string pattern lists:

  • jasypt.encryptor.property.filter.include-sources: Specify the property sources name patterns to be included for decryption
  • jasypt.encryptor.property.filter.exclude-sources: Specify the property sources name patterns to be EXCLUDED for decryption
  • jasypt.encryptor.property.filter.include-names: Specify the property name patterns to be included for decryption
  • jasypt.encryptor.property.filter.exclude-names: Specify the property name patterns to be EXCLUDED for decryption

Provide a customEncryptablePropertyFilter

You can override the default implementation by providing a Bean of typeEncryptablePropertyFilterwith nameencryptablePropertyFilteror if you wanna provide your own bean name, override propertyjasypt.encryptor.property.filter-beanand specify the name you wanna give the bean. When providing this, you'll be responsible for detecting properties and/or property sources you want to contemplate for decryption. Example:

classMyEncryptablePropertyFilterimplementsEncryptablePropertyFilter{

publicbooleanshouldInclude(PropertySource<?>source,Stringname) {
returnname.startsWith('encrypted.');
}
}
@Bean(name="encryptablePropertyFilter")
EncryptablePropertyFilterencryptablePropertyFilter() {
returnnewMyEncryptablePropertyFilter();
}

Notice that for this mechanism to work, you should not provide a customEncryptablePropertyResolverand use the default resolver instead. If you provide custom resolver, you are responsible for the entire process of detecting and decrypting properties.

Filter outPropertySourceclasses from being introspected

Define a comma-separated list of fully-qualified class names to be skipped from introspection. This classes will not be wrapped/proxied by this plugin and thereby properties contained in them won't supported encryption/decryption:

jasypt.encryptor.skip-property-sources=org.springframework.boot.env.RandomValuePropertySource,org.springframework.boot.ansi.AnsiPropertySource

Encryptable Properties cache refresh

Encrypted properties are cached within your application and in certain scenarios, like when using externalized configuration from a config server the properties need to be refreshed when they changed. For thisjasypt-spring-bootregisters a RefreshScopeRefreshedEventListenerthat listens to the following events by default to clear the encrypted properties cache:

publicstaticfinalList<String>EVENT_CLASS_NAMES=Arrays.asList(
"org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent",
"org.springframework.cloud.context.environment.EnvironmentChangeEvent",
"org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent"
);

Should you need to register extra events that you would like to trigger an encrypted cache invalidation you can add them using the following property (separate by comma if more than one needed):

jasypt.encryptor.refreshed-event-classes=org.springframework.boot.context.event.ApplicationStartedEvent

Maven Plugin

A Maven plugin is provided with a number of helpful utilities.

To use the plugin, just add the following to your pom.xml:

<build>
<plugins>
<plugin>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-maven-plugin</artifactId>
<version>3.0.5</version>
</plugin>
</plugins>
</build>

When using this plugin, the easiest way to provide your encryption password is via a system property i.e. -Djasypt.encryptor.password= "the password".

By default, the plugin will consider encryption configuration in standard Spring boot configuration files under ./src/main/resources. You can also use system properties or environment variables to supply this configuration.

Keep in mind that the rest of your application code and resources are not available to the plugin because Maven plugins do not share a classpath with projects. If your application provides encryption configuration via a StringEncryptor bean then this will not be picked up.

In general, it is recommended to just rely on the secure default configuration.

Encryption

To encrypt a single value run:

mvn jasypt:encrypt-value -Djasypt.encryptor.password="the password"-Djasypt.plugin.value="theValueYouWantToEncrypt"

To encrypt placeholders insrc/main/resources/application.properties,simply wrap any string withDEC(...). For example:

sensitive.password=DEC(secret value)
regular.property=example

Then run:

mvn jasypt:encrypt -Djasypt.encryptor.password="the password"

Which would edit that file in place resulting in:

sensitive.password=ENC(encrypted)
regular.property=example

The file name and location can be customised.

Decryption

To decrypt a single value run:

mvn jasypt:decrypt-value -Djasypt.encryptor.password="the password"-Djasypt.plugin.value="DbG1GppXOsFa2G69PnmADvQFI3esceEhJYbaEIKCcEO5C85JEqGAhfcjFMGnoRFf"

To decrypt placeholders insrc/main/resources/application.properties,simply wrap any string withENC(...).For example:

sensitive.password=ENC(encrypted)
regular.property=example

This can be decrypted as follows:

mvn jasypt:decrypt -Djasypt.encryptor.password="the password"

Which would output the decrypted contents to the screen:

sensitive.password=DEC(decrypted)
regular.property=example

Note that outputting to the screen, rather than editing the file in place, is designed to reduce accidental committing of decrypted values to version control. When decrypting, you most likely just want to check what value has been encrypted, rather than wanting to permanently decrypt that value.

Re-encryption

Changing the configuration for existing encrypted properties is slightly awkward using the encrypt/decrypt goals. You must run the decrypt goal using the old configuration, then copy the decrypted output back into the original file, then run the encrypt goal with the new configuration.

The re-encrypt goal simplifies this by re-encrypting a file in place. 2 sets of configuration must be provided. The new configuration is supplied in the same way as you would configure the other maven goals. The old configuration is supplied via system properties prefixed with "jasypt.plugin.old" instead of "jasypt.encryptor".

For example, to re-encrypt application.properties that was previously encrypted with the password OLD and then encrypt with the new password NEW:

mvn jasypt:reencrypt -Djasypt.plugin.old.password=OLD -Djasypt.encryptor.password=NEW

Note: All old configuration must be passed as system properties. Environment variables and Spring Boot configuration files are not supported.

Upgrade

Sometimes the default encryption configuration might change between versions of jasypt-spring-boot. You can automatically upgrade your encrypted properties to the new defaults with the upgrade goal. This will decrypt your application.properties file using the old default configuration and re-encrypt using the new default configuration.

mvn jasypt:upgrade -Djasypt.encryptor.password=EXAMPLE

You can also pass the system property-Djasypt.plugin.old.major-versionto specify the version you are upgrading from. This will always default to the last major version where the configuration changed. Currently, the only major version where the defaults changed is version 2, so there is no need to set this property, but it is there for future use.

Load

You can also decrypt a properties file and load all of its properties into memory and make them accessible to Maven. This is useful when you want to make encrypted properties available to other Maven plugins.

You can chain the goals of the later plugins directly after this one. For example, with flyway:

mvn jasypt:load flyway:migrate -Djasypt.encryptor.password="the password"

You can also specify a prefix for each property with-Djasypt.plugin.keyPrefix=example..This helps to avoid potential clashes with other Maven properties.

Changing the file path

For all the above utilities, the path of the file you are encrypting/decrypting defaults to file:src/main/resources/application.properties.

This can be changed using the-Djasypt.plugin.pathsystem property.

You can encrypt a file in your test resources directory:

mvn jasypt:encrypt -Djasypt.plugin.path="file:src/main/test/application.properties"-Djasypt.encryptor.password="the password"

Or with a different name:

mvn jasypt:encrypt -Djasypt.plugin.path="file:src/main/resources/flyway.properties"-Djasypt.encryptor.password="the password"

Or with a different file type (the plugin supports any plain text file format including YAML):

mvn jasypt:encrypt -Djasypt.plugin.path="file:src/main/resources/application.yaml"-Djasypt.encryptor.password="the password"

Note that the load goal only supports.property files

Spring profiles and other spring config

You can override any spring config you support in your application when running the plugin, for instance selecting a given spring profile:

mvn jasypt:encrypt -Dspring.profiles.active=cloud -Djasypt.encryptor.password="the password"

Multi-module maven projects

To encrypt/decrypt properties in multi-module projects disable recursion with-Nor--non-recursiveon the maven command:

mvn jasypt:upgrade -Djasypt.plugin.path=file:server/src/test/resources/application-test.properties -Djasypt.encryptor.password=supersecret -N

Asymmetric Encryption

jasypt-spring-boot:2.1.1introduces a new feature to encrypt/decrypt properties using asymmetric encryption with a pair of private/public keys in DER or PEM formats.

Config Properties

The following are the configuration properties you can use to config asymmetric decryption of properties;

KeyDefault ValueDescription
jasypt.encryptor.privateKeyStringnullprivate key for decryption in String format
jasypt.encryptor.privateKeyLocationnulllocation of the private key for decryption in spring resource format
jasypt.encryptor.privateKeyFormatDERKey format. DER or PEM

You should either useprivateKeyStringorprivateKeyLocation,the String format takes precedence if set. To specify a private key in DER format withprivateKeyString,please encode the key bytes tobase64.

Notethatjasypt.encryptor.passwordstill takes precedences for PBE encryption over the asymmetric config.

Sample config

DER key as string

jasypt:
encryptor:
privateKeyString: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtB/IYK8E52CYMZTpyIY9U0HqMewyKnRvSo6s+9VNIn/HSh9+MoBGiADa2MaPKvetS3CD3CgwGq/+LIQ1HQYGchRrSORizOcIp7KBx+Wc1riatV/tcpcuFLC1j6QJ7d2I+T7RA98Sx8X39orqlYFQVysTw/aTawX/yajx0UlTW3rNAY+ykeQ0CBHowtTxKM9nGcxLoQbvbYx1iG9JgAqye7TYejOpviOH+BpD8To2S8zcOSojIhixEfayay0gURv0IKJN2LP86wkpAuAbL+mohUq1qLeWdTEBrIRXjlnrWs1M66w0l/6JwaFnGOqEB6haMzE4JWZULYYpr2yKyoGCRAgMBAAECggEAQxURhs1v3D0wgx27ywO3zeoFmPEbq6G9Z6yMd5wk7cMUvcpvoNVuAKCUlY4pMjDvSvCM1znN78g/CnGF9FoxJb106Iu6R8HcxOQ4T/ehS+54kDvL999PSBIYhuOPUs62B/Jer9FfMJ2veuXb9sGh19EFCWlMwILEV/dX+MDyo1qQaNzbzyyyaXP8XDBRDsvPL6fPxL4r6YHywfcPdBfTc71/cEPksG8ts6um8uAVYbLIDYcsWopjVZY/nUwsz49xBCyRcyPnlEUJedyF8HANfVEO2zlSyRshn/F+rrjD6aKBV/yVWfTEyTSxZrBPl4I4Tv89EG5CwuuGaSagxfQpAQKBgQDXEe7FqXSaGk9xzuPazXy8okCX5pT6545EmqTP7/JtkMSBHh/xw8GPp+JfrEJEAJJl/ISbdsOAbU+9KAXuPmkicFKbodBtBa46wprGBQ8XkR4JQoBFj1SJf7Gj9ozmDycozO2Oy8a1QXKhHUPkbPQ0+w3efwoYdfE67ZodpFNhswKBgQDN9eaYrEL7YyD7951WiK0joq0BVBLK3rwO5+4g9IEEQjhP8jSo1DP+zS495t5ruuuuPsIeodA79jI8Ty+lpYqqCGJTE6muqLMJDiy7KlMpe0NZjXrdSh6edywSz3YMX1eAP5U31pLk0itMDTf2idGcZfrtxTLrpRffumowdJ5qqwKBgF+XZ+JRHDN2aEM0atAQr1WEZGNfqG4Qx4o0lfaaNs1+H+knw5kIohrAyvwtK1LgUjGkWChlVCXb8CoqBODMupwFAqKL/IDImpUhc/t5uiiGZqxE85B3UWK/7+vppNyIdaZL13a1mf9sNI/p2whHaQ+3WoW/P3R5z5uaifqM1EbDAoGAN584JnUnJcLwrnuBx1PkBmKxfFFbPeSHPzNNsSK3ERJdKOINbKbaX+7DlT4bRVbWvVj/jcw/c2Ia0QTFpmOdnivjefIuehffOgvU8rsMeIBsgOvfiZGx0TP3+CCFDfRVqjIBt3HAfAFyZfiP64nuzOERslL2XINafjZW5T0pZz8CgYAJ3UbEMbKdvIuK+uTl54R1Vt6FO9T5bgtHR4luPKoBv1ttvSC6BlalgxA0Ts/AQ9tCsUK2JxisUcVgMjxBVvG0lfq/EHpL0Wmn59SHvNwtHU2qx3Ne6M0nQtneCCfR78OcnqQ7+L+3YCMqYGJHNFSard+dewfKoPnWw0WyGFEWCg==

DER key as a resource location

jasypt:
encryptor:
privateKeyLocation:classpath:private_key.der

PEM key as string

jasypt:
encryptor:
privateKeyFormat:PEM
privateKeyString:|-
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtB/IYK8E52CYM
ZTpyIY9U0HqMewyKnRvSo6s+9VNIn/HSh9+MoBGiADa2MaPKvetS3CD3CgwGq/+L
IQ1HQYGchRrSORizOcIp7KBx+Wc1riatV/tcpcuFLC1j6QJ7d2I+T7RA98Sx8X39
orqlYFQVysTw/aTawX/yajx0UlTW3rNAY+ykeQ0CBHowtTxKM9nGcxLoQbvbYx1i
G9JgAqye7TYejOpviOH+BpD8To2S8zcOSojIhixEfayay0gURv0IKJN2LP86wkpA
uAbL+mohUq1qLeWdTEBrIRXjlnrWs1M66w0l/6JwaFnGOqEB6haMzE4JWZULYYpr
2yKyoGCRAgMBAAECggEAQxURhs1v3D0wgx27ywO3zeoFmPEbq6G9Z6yMd5wk7cMU
vcpvoNVuAKCUlY4pMjDvSvCM1znN78g/CnGF9FoxJb106Iu6R8HcxOQ4T/ehS+54
kDvL999PSBIYhuOPUs62B/Jer9FfMJ2veuXb9sGh19EFCWlMwILEV/dX+MDyo1qQ
aNzbzyyyaXP8XDBRDsvPL6fPxL4r6YHywfcPdBfTc71/cEPksG8ts6um8uAVYbLI
DYcsWopjVZY/nUwsz49xBCyRcyPnlEUJedyF8HANfVEO2zlSyRshn/F+rrjD6aKB
V/yVWfTEyTSxZrBPl4I4Tv89EG5CwuuGaSagxfQpAQKBgQDXEe7FqXSaGk9xzuPa
zXy8okCX5pT6545EmqTP7/JtkMSBHh/xw8GPp+JfrEJEAJJl/ISbdsOAbU+9KAXu
PmkicFKbodBtBa46wprGBQ8XkR4JQoBFj1SJf7Gj9ozmDycozO2Oy8a1QXKhHUPk
bPQ0+w3efwoYdfE67ZodpFNhswKBgQDN9eaYrEL7YyD7951WiK0joq0BVBLK3rwO
5+4g9IEEQjhP8jSo1DP+zS495t5ruuuuPsIeodA79jI8Ty+lpYqqCGJTE6muqLMJ
Diy7KlMpe0NZjXrdSh6edywSz3YMX1eAP5U31pLk0itMDTf2idGcZfrtxTLrpRff
umowdJ5qqwKBgF+XZ+JRHDN2aEM0atAQr1WEZGNfqG4Qx4o0lfaaNs1+H+knw5kI
ohrAyvwtK1LgUjGkWChlVCXb8CoqBODMupwFAqKL/IDImpUhc/t5uiiGZqxE85B3
UWK/7+vppNyIdaZL13a1mf9sNI/p2whHaQ+3WoW/P3R5z5uaifqM1EbDAoGAN584
JnUnJcLwrnuBx1PkBmKxfFFbPeSHPzNNsSK3ERJdKOINbKbaX+7DlT4bRVbWvVj/
jcw/c2Ia0QTFpmOdnivjefIuehffOgvU8rsMeIBsgOvfiZGx0TP3+CCFDfRVqjIB
t3HAfAFyZfiP64nuzOERslL2XINafjZW5T0pZz8CgYAJ3UbEMbKdvIuK+uTl54R1
Vt6FO9T5bgtHR4luPKoBv1ttvSC6BlalgxA0Ts/AQ9tCsUK2JxisUcVgMjxBVvG0
lfq/EHpL0Wmn59SHvNwtHU2qx3Ne6M0nQtneCCfR78OcnqQ7+L+3YCMqYGJHNFSa
rd+dewfKoPnWw0WyGFEWCg==
-----END PRIVATE KEY-----

PEM key as a resource location

jasypt:
encryptor:
privateKeyFormat:PEM
privateKeyLocation:classpath:private_key.pem

Encrypting properties

There is no program/command to encrypt properties using asymmetric keys but you can use the following code snippet to encrypt your properties:

DER Format

importcom.ulisesbocchio.jasyptspringboot.encryptor.SimpleAsymmetricConfig;
importcom.ulisesbocchio.jasyptspringboot.encryptor.SimpleAsymmetricStringEncryptor;
importorg.jasypt.encryption.StringEncryptor;

publicclassPropertyEncryptor{
publicstaticvoidmain(String[]args) {
SimpleAsymmetricConfigconfig=newSimpleAsymmetricConfig();
config.setPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArQfyGCvBOdgmDGU6ciGPVNB6jHsMip0b0qOrPvVTSJ/x0offjKARogA2tjGjyr3rUtwg9woMBqv/iyENR0GBnIUa0jkYsznCKeygcflnNa4mrVf7XKXLhSwtY+kCe3diPk+0QPfEsfF9/aK6pWBUFcrE8P2k2sF/8mo8dFJU1t6zQGPspHkNAgR6MLU8SjPZxnMS6EG722MdYhvSYAKsnu02Hozqb4jh/gaQ/E6NkvM3DkqIyIYsRH2smstIFEb9CCiTdiz/OsJKQLgGy/pqIVKtai3lnUxAayEV45Z61rNTOusNJf+icGhZxjqhAeoWjMxOCVmVC2GKa9sisqBgkQIDAQAB");
StringEncryptorencryptor=newSimpleAsymmetricStringEncryptor(config);
Stringmessage="chupacabras";
Stringencrypted=encryptor.encrypt(message);
System.out.printf("Encrypted message %s\n",encrypted);
}
}

PEM Format

importcom.ulisesbocchio.jasyptspringboot.encryptor.SimpleAsymmetricConfig;
importcom.ulisesbocchio.jasyptspringboot.encryptor.SimpleAsymmetricStringEncryptor;
importorg.jasypt.encryption.StringEncryptor;
importstaticcom.ulisesbocchio.jasyptspringboot.util.AsymmetricCryptography.KeyFormat.PEM;

publicclassPropertyEncryptor{
publicstaticvoidmain(String[]args) {
SimpleAsymmetricConfigconfig=newSimpleAsymmetricConfig();
config.setKeyFormat(PEM);
config.setPublicKey("-----BEGIN PUBLIC KEY-----\n"+
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArQfyGCvBOdgmDGU6ciGP\n"+
"VNB6jHsMip0b0qOrPvVTSJ/x0offjKARogA2tjGjyr3rUtwg9woMBqv/iyENR0GB\n"+
"nIUa0jkYsznCKeygcflnNa4mrVf7XKXLhSwtY+kCe3diPk+0QPfEsfF9/aK6pWBU\n"+
"FcrE8P2k2sF/8mo8dFJU1t6zQGPspHkNAgR6MLU8SjPZxnMS6EG722MdYhvSYAKs\n"+
"nu02Hozqb4jh/gaQ/E6NkvM3DkqIyIYsRH2smstIFEb9CCiTdiz/OsJKQLgGy/pq\n"+
"IVKtai3lnUxAayEV45Z61rNTOusNJf+icGhZxjqhAeoWjMxOCVmVC2GKa9sisqBg\n"+
"kQIDAQAB\n"+
"-----END PUBLIC KEY-----\n");
StringEncryptorencryptor=newSimpleAsymmetricStringEncryptor(config);
Stringmessage="chupacabras";
Stringencrypted=encryptor.encrypt(message);
System.out.printf("Encrypted message %s\n",encrypted);
}
}

AES 256-GCM Encryption

As of version 3.0.5, AES 256-GCM Encryption is supported. To use this type of encryption, set the propertyjasypt.encryptor.gcm-secret-key-string,jasypt.encryptor.gcm-secret-key-locationorjasypt.encryptor.gcm-secret-key-password.
The underlying algorithm used isAES/GCM/NoPaddingso make sure that's installed in your JDK.
TheSimpleGCMByteEncryptoruses aIVGeneratorto encrypt properties. You can configure that with propertyjasypt.encryptor.iv-generator-classnameif you don't want to use the default implementationRandomIvGenerator

Using a key

When using a key viajasypt.encryptor.gcm-secret-key-stringorjasypt.encryptor.gcm-secret-key-location,make sure you encode your key in base64. The base64 string value could set tojasypt.encryptor.gcm-secret-key-string,or just can save it in a file and use a spring resource locator to that file in propertyjasypt.encryptor.gcm-secret-key-location.For instance:

jasypt.encryptor.gcm-secret-key-string="PNG5egJcwiBrd+E8go1tb9PdPvuRSmLSV3jjXBmWlIU="
#OR
jasypt.encryptor.gcm-secret-key-location=classpath:secret_key.b64
#OR
jasypt.encryptor.gcm-secret-key-location=file:/full/path/secret_key.b64
#OR
jasypt.encryptor.gcm-secret-key-location=file:relative/path/secret_key.b64

Optionally, you can create your ownStringEncryptorbean:

@Bean("encryptorBean")
publicStringEncryptorstringEncryptor() {
SimpleGCMConfigconfig=newSimpleGCMConfig();
config.setSecretKey("PNG5egJcwiBrd+E8go1tb9PdPvuRSmLSV3jjXBmWlIU=");
returnnewSimpleGCMStringEncryptor(config);
}

Using a password

Alternatively, you can use a password to encrypt/decrypt properties using AES 256-GCM. The password is used to generate a key on startup, so there is a few properties you need to/can set, these are:

jasypt.encryptor.gcm-secret-key-password="chupacabras"
#Optional, defaults to "1000"
jasypt.encryptor.key-obtention-iterations="1000"
#Optional, defaults to 0, no salt. If provided, specify the salt string in ba64 format
jasypt.encryptor.gcm-secret-key-salt="HrqoFr44GtkAhhYN+jP8Ag=="
#Optional, defaults to PBKDF2WithHmacSHA256
jasypt.encryptor.gcm-secret-key-algorithm="PBKDF2WithHmacSHA256"

Make sure this parameters are the same if you're encrypting your secrets with external tools. Optionally, you can create your ownStringEncryptorbean:

@Bean("encryptorBean")
publicStringEncryptorstringEncryptor() {
SimpleGCMConfigconfig=newSimpleGCMConfig();
config.setSecretKeyPassword("chupacabras");
config.setSecretKeyIterations(1000);
config.setSecretKeySalt("HrqoFr44GtkAhhYN+jP8Ag==");
config.setSecretKeyAlgorithm("PBKDF2WithHmacSHA256");
returnnewSimpleGCMStringEncryptor(config);
}

Encrypting properties with AES GCM-256

You can use theMaven Pluginor follow a similar strategy as explained inAsymmetric Encryption'sEncrypting Properties

Demo App

Thejasypt-spring-boot-demo-samplesrepo contains working Spring Boot app examples. The mainjasypt-spring-boot-demoDemo app explicitly sets a System property with the encryption password before the app runs. To have a little more realistic scenario try removing the line where the system property is set, build the app with maven, and the run:

java -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar --jasypt.encryptor.password=password

And you'll be passing the encryption password as a command line argument. Run it like this:

java -Djasypt.encryptor.password=password -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar

And you'll be passing the encryption password as a System property.

If you need to pass this property as an Environment Variable you can accomplish this by creating application.properties or application.yml and adding:

jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}

or in YAML

jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD:}

basically what this does is to define thejasypt.encryptor.passwordproperty pointing to a different propertyJASYPT_ENCRYPTOR_PASSWORDthat you can set with an Environment Variable, and you can also override via System Properties. This technique can also be used to translate property name/values for any other library you need. This is also available in the Demo app. So you can run the Demo app like this:

JASYPT_ENCRYPTOR_PASSWORD=password java -jar target/jasypt-spring-boot-demo-1.5-SNAPSHOT.jar

Note:When using Gradle as build tool, processResources task fails because of '$' character, to solve this you just need to scape this variable like this '\$'.

Other Demo Apps

Whilejasypt-spring-boot-demois a comprehensive Demo that showcases all possible ways to encrypt/decrypt properties, there are other multiple Demos that demo isolated scenarios.