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

Reply via email to