This is an automated email from the ASF dual-hosted git repository.
Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
The following commit(s) were added to refs/heads/main by this push:
new ae1e5f6163a CAMEL-24506: camel-jasypt-starter - modern default
algorithm and safer usage example
ae1e5f6163a is described below
commit ae1e5f6163a367f9d8a62885e210fa4b0afedf9a
Author: croway <[email protected]>
AuthorDate: Wed Sep 2 14:50:02 2026 +0200
CAMEL-24506: camel-jasypt-starter - modern default algorithm and safer
usage example
The starter defaulted `camel.component.jasypt.algorithm` to
`PBEWithMD5AndDES`,
a 56-bit DES cipher with MD5-based key derivation, and that value flowed
into
`EnvironmentStringPBEConfig.setAlgorithm` on every decryption path. The
starter
already carries `PBEWITHHMACSHA256ANDAES_256` in
`JasyptEncryptedPropertiesUtils.ALGORITHMS_THAT_REQUIRE_IV`, so making it
the
default engages the existing `RandomIvGenerator` path automatically, with
no new
machinery.
The default is now `PBEWITHHMACSHA256ANDAES_256`. This is a breaking change
for
values encrypted under the previous default; those can still be read by
pinning
`camel.component.jasypt.algorithm = PBEWithMD5AndDES`. The javadoc and the
generated configuration metadata document both the new default and the
opt-back.
The upstream `camel-jasypt` component leaves the algorithm unset, so it
still
falls back to the Jasypt library default of `PBEWithMD5AndDES`. Aligning it
is a
separate change; the documentation therefore spells out that the encryption
tooling must be given a matching `-a` and a random IV generator, since the
Jasypt
CLI installs no IV generator unless asked.
The usage example also placed `camel.component.jasypt.password` in the same
properties block as the `ENC(...)` value, which defeats the purpose of
encrypting
it. It now uses `sysenv:JASYPT_PASSWORD`, carries a warning that the master
password must not live beside the ciphertext, and documents the `sysenv:`
and
`sys:` prefixes the code already supports.
Tests: `JasyptDefaultAlgorithmTest` covers the default algorithm and its IV
generator, an encrypt/decrypt round trip under the default, decryption of a
legacy-algorithm value with the opt-back set, and the failure of that value
under
the new default. `EncryptedPropertiesUtilsTest` is updated for the IV
auto-detection now triggered by the default, with a new case for an
algorithm
that does not require an IV.
Co-Authored-By: Claude Opus 5 <[email protected]>
---
.../camel-jasypt-starter/src/main/doc/usage.adoc | 41 +++++++++-
.../camel-jasypt-starter/src/main/docs/jasypt.json | 6 +-
.../JasyptEncryptedPropertiesConfiguration.java | 10 ++-
.../springboot/EncryptedPropertiesUtilsTest.java | 11 ++-
.../springboot/JasyptDefaultAlgorithmTest.java | 94 ++++++++++++++++++++++
.../modules/ROOT/pages/starters/jasypt.adoc | 45 +++++++++--
6 files changed, 190 insertions(+), 17 deletions(-)
diff --git a/components-starter/camel-jasypt-starter/src/main/doc/usage.adoc
b/components-starter/camel-jasypt-starter/src/main/doc/usage.adoc
index a12863cd3c4..b539d6ec860 100644
--- a/components-starter/camel-jasypt-starter/src/main/doc/usage.adoc
+++ b/components-starter/camel-jasypt-starter/src/main/doc/usage.adoc
@@ -1,14 +1,47 @@
-Add encrypted values to your `application.properties` using the `ENC(...)`
syntax:
+Add encrypted values to your `application.properties` using the `ENC(...)`
syntax, and point the starter at the master
+password:
[source,properties]
----
my.secret = ENC(encrypted-value-here)
-camel.component.jasypt.password = the-master-password
+camel.component.jasypt.password = sysenv:JASYPT_PASSWORD
----
-Use Camel's Jasypt tooling to encrypt values:
+WARNING: The master password must never be stored in the same file, or the
same repository, as the encrypted values it
+protects. A file that carries both the ciphertext and the key that unlocks it
is no better than a plaintext file. Supply
+the master password from the environment or from an external secret store at
deployment time.
+
+`camel.component.jasypt.password` understands two prefixes that keep the
password out of the configuration file:
+
+* `sysenv:<name>` looks the password up in the OS environment variable
`<name>`.
+* `sys:<name>` looks the password up in the JVM system property `<name>`.
+
+Any other value is used as the password verbatim, which is only appropriate
when the property itself is injected by an
+external secret store (for example a mounted secret or a config server) rather
than checked in.
+
+=== Encryption algorithm
+
+The default algorithm is `PBEWITHHMACSHA256ANDAES_256`. It requires an
initialization vector, which the starter
+generates automatically (`org.jasypt.iv.RandomIvGenerator`) unless
`camel.component.jasypt.iv-generator-class-name` is
+set explicitly.
+
+Use Jasypt tooling to encrypt values, passing the *same* algorithm and a
random IV generator; a value encrypted under a
+different algorithm, or without an IV generator, cannot be decrypted at
runtime:
[source,bash]
----
-camel jasypt encrypt --password=the-master-password --input=my-secret-value
+jbang org.apache.camel:camel-jasypt:<camel-version> \
+ -c encrypt -p "$JASYPT_PASSWORD" -i my-secret-value \
+ -a PBEWITHHMACSHA256ANDAES_256 -riga SHA1PRNG
+----
+
+NOTE: The `camel-jasypt` CLI entrypoint is deprecated. The `encrypt.sh` script
shipped in the
+https://github.com/jasypt/jasypt/releases/tag/jasypt-1.9.3[Jasypt
distribution] provides the same workflow, and takes
+the algorithm and IV generator through its own `algorithm` and
`ivGeneratorClassName` arguments.
+
+To keep reading values that were encrypted with the previous default
algorithm, pin it explicitly:
+
+[source,properties]
+----
+camel.component.jasypt.algorithm = PBEWithMD5AndDES
----
diff --git a/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
b/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
index 1b83e21b472..2656cc8774f 100644
--- a/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
+++ b/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
@@ -10,9 +10,9 @@
{
"name": "camel.component.jasypt.algorithm",
"type": "java.lang.String",
- "description": "The algorithm to be used for decryption. Default:
PBEWithMD5AndDES",
+ "description": "The algorithm to be used for decryption. Default:
PBEWITHHMACSHA256ANDAES_256. This algorithm requires an initialization vector,
which is generated automatically unless ivGeneratorClassName is set explicitly.
Values encrypted with a different algorithm can only be decrypted by setting
this option to that algorithm, for example PBEWithMD5AndDES.",
"sourceType":
"org.apache.camel.component.jasypt.springboot.JasyptEncryptedPropertiesConfiguration",
- "defaultValue": "PBEWithMD5AndDES"
+ "defaultValue": "PBEWITHHMACSHA256ANDAES_256"
},
{
"name": "camel.component.jasypt.early-decryption-enabled",
@@ -37,7 +37,7 @@
{
"name": "camel.component.jasypt.password",
"type": "java.lang.String",
- "description": "The master password used by Jasypt for decrypting the
values. This option supports prefixes which influence the master password
lookup behaviour: sysenv: means to lookup the OS system environment with the
given key. sys: means to lookup a JVM system property.",
+ "description": "The master password used by Jasypt for decrypting the
values. This option supports prefixes which influence the master password
lookup behaviour: sysenv: means to lookup the OS system environment with the
given key. sys: means to lookup a JVM system property. The master password
should be supplied through one of those prefixes, or from an external secret
store, and should not be stored alongside the encrypted values it protects.",
"sourceType":
"org.apache.camel.component.jasypt.springboot.JasyptEncryptedPropertiesConfiguration"
},
{
diff --git
a/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
b/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
index e721dfad164..a753a16d63c 100644
---
a/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
+++
b/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
@@ -37,14 +37,18 @@ public class JasyptEncryptedPropertiesConfiguration {
private boolean earlyDecryptionEnabled;
/**
- * The algorithm to be used for decryption. Default: PBEWithMD5AndDES
+ * The algorithm to be used for decryption. Default:
PBEWITHHMACSHA256ANDAES_256. This algorithm requires an
+ * initialization vector, which is generated automatically unless
ivGeneratorClassName is set explicitly. Values
+ * encrypted with a different algorithm can only be decrypted by setting
this option to that algorithm, for example
+ * PBEWithMD5AndDES.
*/
- private String algorithm = "PBEWithMD5AndDES";
+ private String algorithm = "PBEWITHHMACSHA256ANDAES_256";
/**
* The master password used by Jasypt for decrypting the values. This
option supports prefixes which influence the
* master password lookup behaviour: sysenv: means to lookup the OS system
environment with the given key. sys:
- * means to lookup a JVM system property.
+ * means to lookup a JVM system property. The master password should be
supplied through one of those prefixes, or
+ * from an external secret store, and should not be stored alongside the
encrypted values it protects.
*/
private String password;
diff --git
a/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EncryptedPropertiesUtilsTest.java
b/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EncryptedPropertiesUtilsTest.java
index 1070a51b9cf..982cbaf2ecd 100644
---
a/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EncryptedPropertiesUtilsTest.java
+++
b/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EncryptedPropertiesUtilsTest.java
@@ -30,9 +30,18 @@ public class EncryptedPropertiesUtilsTest {
@Test
public void noIvGeneratorPropertyTest() {
- // IVGenerator is null
+ // IVGenerator is not configured, the default algorithm requires one
so it is auto detected
JasyptEncryptedPropertiesConfiguration configuration = new
JasyptEncryptedPropertiesConfiguration();
IvGenerator ivGenerator = getIVGenerator(configuration);
+ assertThat(ivGenerator).isInstanceOf(RandomIvGenerator.class);
+ }
+
+ @Test
+ public void noIvGeneratorPropertyWithAlgorithmThatDoesNotNeedIvTest() {
+ // IVGenerator is not configured and the algorithm does not require one
+ JasyptEncryptedPropertiesConfiguration configuration = new
JasyptEncryptedPropertiesConfiguration();
+ configuration.setAlgorithm("PBEWithMD5AndDES");
+ IvGenerator ivGenerator = getIVGenerator(configuration);
assertThat(ivGenerator).isInstanceOf(NoIvGenerator.class);
}
diff --git
a/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/JasyptDefaultAlgorithmTest.java
b/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/JasyptDefaultAlgorithmTest.java
new file mode 100644
index 00000000000..b4485f96b4b
--- /dev/null
+++
b/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/JasyptDefaultAlgorithmTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jasypt.springboot;
+
+import org.jasypt.encryption.StringEncryptor;
+import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
+import org.jasypt.exceptions.EncryptionOperationNotPossibleException;
+import org.jasypt.iv.NoIvGenerator;
+import org.jasypt.iv.RandomIvGenerator;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+/**
+ * Verifies the default encryption algorithm of the starter, and that values
encrypted with the previous default can
+ * still be read by pinning that algorithm explicitly.
+ */
+public class JasyptDefaultAlgorithmTest {
+
+ private static final String DEFAULT_ALGORITHM =
"PBEWITHHMACSHA256ANDAES_256";
+
+ private static final String LEGACY_ALGORITHM = "PBEWithMD5AndDES";
+
+ private static final String PLAIN_TEXT = "mysecret";
+
+ private static final String MASTER_PASSWORD = "legacy-master-password";
+
+ /**
+ * {@value #PLAIN_TEXT} encrypted with {@value #LEGACY_ALGORITHM}, the
master password {@value #MASTER_PASSWORD} and
+ * no initialization vector generator, which is how the starter encrypted
values before the default changed.
+ */
+ private static final String LEGACY_ENCRYPTED_VALUE =
"+1thxaTtHh5z+yuyvFlCl5gafagmagQV";
+
+ private final ApplicationContextRunner runner = new
ApplicationContextRunner()
+
.withConfiguration(AutoConfigurations.of(JasyptEncryptedPropertiesAutoconfiguration.class))
+ .withPropertyValues("camel.component.jasypt.password=" +
MASTER_PASSWORD);
+
+ @Test
+ public void defaultAlgorithmRequiresAndGetsAnInitializationVector() {
+ runner.run(context -> {
+
assertThat(context.getBean(JasyptEncryptedPropertiesConfiguration.class).getAlgorithm())
+ .isEqualTo(DEFAULT_ALGORITHM);
+ EnvironmentStringPBEConfig config =
context.getBean(EnvironmentStringPBEConfig.class);
+ assertThat(config.getAlgorithm()).isEqualTo(DEFAULT_ALGORITHM);
+
assertThat(config.getIvGenerator()).isInstanceOf(RandomIvGenerator.class);
+ });
+ }
+
+ @Test
+ public void defaultAlgorithmEncryptsAndDecrypts() {
+ runner.run(context -> {
+ StringEncryptor encryptor = context.getBean(StringEncryptor.class);
+ String encrypted = encryptor.encrypt(PLAIN_TEXT);
+ assertThat(encrypted).isNotEqualTo(PLAIN_TEXT);
+ assertThat(encryptor.decrypt(encrypted)).isEqualTo(PLAIN_TEXT);
+ });
+ }
+
+ @Test
+ public void legacyAlgorithmCanBePinnedExplicitly() {
+ runner.withPropertyValues("camel.component.jasypt.algorithm=" +
LEGACY_ALGORITHM).run(context -> {
+ EnvironmentStringPBEConfig config =
context.getBean(EnvironmentStringPBEConfig.class);
+ assertThat(config.getAlgorithm()).isEqualTo(LEGACY_ALGORITHM);
+
assertThat(config.getIvGenerator()).isInstanceOf(NoIvGenerator.class);
+
assertThat(context.getBean(StringEncryptor.class).decrypt(LEGACY_ENCRYPTED_VALUE)).isEqualTo(PLAIN_TEXT);
+ });
+ }
+
+ @Test
+ public void legacyValueIsNotReadableUnderTheDefaultAlgorithm() {
+ runner.run(context -> {
+ StringEncryptor encryptor = context.getBean(StringEncryptor.class);
+
assertThatExceptionOfType(EncryptionOperationNotPossibleException.class)
+ .isThrownBy(() ->
encryptor.decrypt(LEGACY_ENCRYPTED_VALUE));
+ });
+ }
+}
diff --git a/docs/spring-boot/modules/ROOT/pages/starters/jasypt.adoc
b/docs/spring-boot/modules/ROOT/pages/starters/jasypt.adoc
index 444cdcae068..bdeb2ba772a 100644
--- a/docs/spring-boot/modules/ROOT/pages/starters/jasypt.adoc
+++ b/docs/spring-boot/modules/ROOT/pages/starters/jasypt.adoc
@@ -19,19 +19,52 @@ This starter integrates http://www.jasypt.org[Jasypt] with
both Camel's property
== Usage
-Add encrypted values to your `application.properties` using the `ENC(...)`
syntax:
+Add encrypted values to your `application.properties` using the `ENC(...)`
syntax, and point the starter at the master
+password:
[source,properties]
----
my.secret = ENC(encrypted-value-here)
-camel.component.jasypt.password = the-master-password
+camel.component.jasypt.password = sysenv:JASYPT_PASSWORD
----
-Use Camel's Jasypt tooling to encrypt values:
+WARNING: The master password must never be stored in the same file, or the
same repository, as the encrypted values it
+protects. A file that carries both the ciphertext and the key that unlocks it
is no better than a plaintext file. Supply
+the master password from the environment or from an external secret store at
deployment time.
+
+`camel.component.jasypt.password` understands two prefixes that keep the
password out of the configuration file:
+
+* `sysenv:<name>` looks the password up in the OS environment variable
`<name>`.
+* `sys:<name>` looks the password up in the JVM system property `<name>`.
+
+Any other value is used as the password verbatim, which is only appropriate
when the property itself is injected by an
+external secret store (for example a mounted secret or a config server) rather
than checked in.
+
+=== Encryption algorithm
+
+The default algorithm is `PBEWITHHMACSHA256ANDAES_256`. It requires an
initialization vector, which the starter
+generates automatically (`org.jasypt.iv.RandomIvGenerator`) unless
`camel.component.jasypt.iv-generator-class-name` is
+set explicitly.
+
+Use Jasypt tooling to encrypt values, passing the *same* algorithm and a
random IV generator; a value encrypted under a
+different algorithm, or without an IV generator, cannot be decrypted at
runtime:
[source,bash]
----
-camel jasypt encrypt --password=the-master-password --input=my-secret-value
+jbang org.apache.camel:camel-jasypt:<camel-version> \
+ -c encrypt -p "$JASYPT_PASSWORD" -i my-secret-value \
+ -a PBEWITHHMACSHA256ANDAES_256 -riga SHA1PRNG
+----
+
+NOTE: The `camel-jasypt` CLI entrypoint is deprecated. The `encrypt.sh` script
shipped in the
+https://github.com/jasypt/jasypt/releases/tag/jasypt-1.9.3[Jasypt
distribution] provides the same workflow, and takes
+the algorithm and IV generator through its own `algorithm` and
`ivGeneratorClassName` arguments.
+
+To keep reading values that were encrypted with the previous default
algorithm, pin it explicitly:
+
+[source,properties]
+----
+camel.component.jasypt.algorithm = PBEWithMD5AndDES
----
== Spring Boot Auto-Configuration
@@ -41,11 +74,11 @@ The starter supports 9 options, which are listed below.
[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
-| camel.component.jasypt.algorithm | The algorithm to be used for decryption.
Default: PBEWithMD5AndDES | PBEWithMD5AndDES | String
+| camel.component.jasypt.algorithm | The algorithm to be used for decryption.
Default: PBEWITHHMACSHA256ANDAES_256. This algorithm requires an initialization
vector, which is generated automatically unless ivGeneratorClassName is set
explicitly. Values encrypted with a different algorithm can only be decrypted
by setting this option to that algorithm, for example PBEWithMD5AndDES. |
PBEWITHHMACSHA256ANDAES_256 | String
| camel.component.jasypt.early-decryption-enabled | Enable the early
properties decryption during Spring Start Up. Enabling this feature, encrypted
properties can be decrypted before the Spring Boot AutoConfiguration kicks in,
for example,
server.port=ENC(oBpQDDUvFY0c4WNAG0o4LIS5bWqmlxYlUUDTW2iXJIAZFYvM+3vOredaMcVfL4xW)
will be decrypted to 8082, and the application will start using that port. |
false | Boolean
| camel.component.jasypt.enabled | Enable the component | false | Boolean
| camel.component.jasypt.iv-generator-class-name | The initialization vector
(IV) generator applied in decryption operations. Default: org.jasypt.iv. | |
String
-| camel.component.jasypt.password | The master password used by Jasypt for
decrypting the values. This option supports prefixes which influence the master
password lookup behaviour: sysenv: means to lookup the OS system environment
with the given key. sys: means to lookup a JVM system property. | | String
+| camel.component.jasypt.password | The master password used by Jasypt for
decrypting the values. This option supports prefixes which influence the master
password lookup behaviour: sysenv: means to lookup the OS system environment
with the given key. sys: means to lookup a JVM system property. The master
password should be supplied through one of those prefixes, or from an external
secret store, and should not be stored alongside the encrypted values it
protects. | | String
| camel.component.jasypt.provider-name | The class name of the security
provider to be used for obtaining the encryption algorithm. | | String
| camel.component.jasypt.random-iv-generator-algorithm | The algorithm for the
random iv generator | SHA1PRNG | String
| camel.component.jasypt.random-salt-generator-algorithm | The algorithm for
the salt generator | SHA1PRNG | String