Encrypted property placeholders are a great way to store and use database, API or broker user IDs and passwords. Red Hat JBoss Fuse utilizes Jasypt Simplified Encryption to encrypt property values.

To use the Jasypt functionality in Red Hat JBoss Fuse you have to export the JASYPT_ENCRYPTION_PASSWORD variable before starting the server. The jasypt-encryption and the camel-jasypt features should already be installed by default in the standalone Fuse install. In Fabric mode the camel-jasypt and the jasypt-encryption features need to be part of your profile.

Export the encryption password

[fedora@sparekh]$ export JASYPT_ENCRYPTION_PASSWORD=s3cr3t

Verify Jasypt install on Fuse

To check if the features are installed on your fuse instance you can run the following command in the karaf shell:

features:list -i | grep jasypt
Checking for Jasypt features in Karaf shell

Checking for Jasypt features in Karaf shell

Or you can also check in the Hawtio webconsole by navigating to the OSGi → Features tab:

Checking for Jasypt features in Hawtio webconsole

Checking for Jasypt features in Hawtio webconsole

Use encrypted properties in a Camel route

I have modified the sample blueprint route based on the camel-blueprint-archetype to show a working camel route with encrypted properties. The project is hosted on GitHub here: camel-blueprint-encrypted

The changes I made to the vanilla camel-blueprint-archetype are explained below.

Before we set up a Camel route to decrypt a property we have to encrypt it. Download the Jasypt v1.9.2 binaries from SourceForge. After you unzip the project, head over to the bin directory.

Encrypt the word ‘Camel’ using the encrypt.sh script.

Note: Your encrypted output will not be the same as mine.

[fedora@sparekh]$ ./encrypt.sh input="Camel" password=s3cr3t algorithm=PBEWITHMD5ANDDES

----ENVIRONMENT-----------------

Runtime: Oracle Corporation OpenJDK 64-Bit Server VM 25.65-b01



----ARGUMENTS-------------------

algorithm: PBEWITHMD5ANDDES
input: Camel
password: s3cr3t



----OUTPUT----------------------

orS/w2nwBZ7YoJCTqtp54g==

There are some extra steps involved if you want to use encrypted properties in your Blueprint Camel routes.

First, add the Jasypt dependency and Import-Package information to the project pom.

...
<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.jasypt</artifactId>
    <version>1.9.2_1</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.apache.karaf.jaas</groupId>
    <artifactId>org.apache.karaf.jaas.jasypt</artifactId>
    <version>2.4.0.redhat-620133</version>
    <scope>runtime</scope>
</dependency>
...
<!-- to generate the MANIFEST-FILE of the bundle -->
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>2.3.7</version>
    <extensions>true</extensions>
    <executions>
        <execution>
            <id>bundle-manifest</id>
            <phase>process-classes</phase>
            <goals>
                <goal>manifest</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>camel-blueprint-encrypted</Bundle-SymbolicName>
            <Private-Package>com.shaishav.camel.blueprint.test</Private-Package>
            <Import-Package>org.jasypt.encryption.pbe;version=1.9.2, org.jasypt.encryption.pbe.config;version=1.9.2, org.osgi.service.blueprint</Import-Package>
        </instructions>
        </configuration>
</plugin>
...

Second, replace the plaintext value with the encrypted value in your property file enclosed by ENC()

body.text=ENC(orS/w2nwBZ7YoJCTqtp54g==)

Third, you have to add the enc and cm namespaces to your Blueprint XML.

xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0"

Fourth, add the cm and the enc section to your Blueprint XML.

<cm:property-placeholder id="test.props.placeholder" persistent-id="test.props" update-strategy="none" />

<enc:property-placeholder>
    <enc:encryptor class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
        <property name="config">
            <bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
                <property name="algorithm" value="PBEWithMD5AndDES" />
                <property name="passwordEnvName" value="JASYPT_ENCRYPTION_PASSWORD" />
            </bean>
        </property>
    </enc:encryptor>
</enc:property-placeholder>

The cm section specifies the name of the .cfg file used to populate properties. In the above example the Camel route expects a file, test.props.cfg, in the etc/ directory of JBoss Fuse.

The enc section configures the decryption settings for the encrypted properties. In the above example the enc:property-placeholder is configured with the same settings that we encrypted the property.

Blueprint will now handle decrypting the property at Camel route startup. To verify you can run mvn clean verify on the sample project. Make sure you export the JASYPT_ENCRYPTION_PASSWORD before running the test as the password is required to decrypt successfully.

[mel-1) thread #0 - timer://foo] timerToLog                     INFO  The message contains Camel at 2015-12-21 22:14:37

Full Test Output:

[fedora@sparekh]$ mvn clean verify
...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.redhat.camel.blueprint.test.RouteTest
[                          main] CamelBlueprintHelper           INFO  Using Blueprint XML file: /home/sparekh/Repos/camel-blueprint-encrypted/target/classes/OSGI-INF/blueprint/blueprint.xml
[                      Thread-0] RawBuilder                     INFO  Copy thread finished.
[                          main] Activator                      INFO  Camel activator starting
[                          main] Activator                      INFO  Camel activator started
[                          main] BlueprintExtender              INFO  No quiesce support is available, so blueprint components will not participate in quiesce operations
[         Blueprint Extender: 1] BlueprintContainerImpl         INFO  Bundle camel-blueprint-encrypted is waiting for namespace handlers [http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0, http://karaf.apache.org/xmlns/jasypt/v1.0.0, http://camel.apache.org/schema/blueprint]
[         Blueprint Extender: 1] BlueprintContainerImpl         INFO  Bundle org.apache.karaf.jaas.modules is waiting for namespace handlers [http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0, http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0, http://karaf.apache.org/xmlns/jaas/v1.0.0]
[                          main] CamelBlueprintHelper           INFO  Updating ConfigAdmin Configuration PID=test.props, factoryPID=null, bundleLocation=file:pojosr by overriding properties {body.text=ENC(/80CXuZkx1uSPqkhczVr3Q==)}
[                          main] RouteTest                      INFO  ********************************************************************************
[                          main] RouteTest                      INFO  Testing: testRoute(com.redhat.camel.blueprint.test.RouteTest)
[                          main] RouteTest                      INFO  ********************************************************************************
[                          main] RouteTest                      INFO  Skipping starting CamelContext as system property skipStartingCamelContext is set to be true.
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-1) is starting
[                          main] DefaultManagementStrategy      INFO  JMX is disabled
[                          main] BlueprintCamelContext          INFO  AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as it may improve performance.
[                          main] BlueprintCamelContext          INFO  StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
[                          main] BlueprintCamelContext          INFO  Route: timerToLog started and consuming from: Endpoint[timer://foo?period=5000]
[                          main] BlueprintCamelContext          INFO  Total 1 routes, of which 1 is started.
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-1) started in 0.304 seconds
[                          main] MockEndpoint                   INFO  Asserting: Endpoint[mock://result] is satisfied
[mel-1) thread #0 - timer://foo] timerToLog                     INFO  The message contains Camel at 2015-12-21 22:14:37
[                          main] RouteTest                      INFO  ********************************************************************************
[                          main] RouteTest                      INFO  Testing done: testRoute(com.redhat.camel.blueprint.test.RouteTest)
[                          main] RouteTest                      INFO  Took: 1.349 seconds (1349 millis)
[                          main] RouteTest                      INFO  ********************************************************************************
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-1) is shutting down
[                          main] DefaultShutdownStrategy        INFO  Starting to graceful shutdown 1 routes (timeout 10 seconds)
[el-1) thread #1 - ShutdownTask] DefaultShutdownStrategy        INFO  Route: timerToLog shutdown complete, was consuming from: Endpoint[timer://foo?period=5000]
[                          main] DefaultShutdownStrategy        INFO  Graceful shutdown of 1 routes completed in 0 seconds
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-1) uptime 1.389 seconds
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-1) is shutdown in 0.038 seconds
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle RouteTest
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle org.apache.karaf.jaas.modules
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle camel-blueprint-encrypted
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-2) is shutting down
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-2) uptime not started
[                          main] BlueprintCamelContext          INFO  Apache Camel 2.15.1.redhat-620133 (CamelContext: camel-2) is shutdown in 0.005 seconds
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle org.apache.aries.blueprint
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle org.apache.camel.camel-blueprint
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle org.apache.karaf.jaas.config
[                          main] BlueprintExtender              INFO  Destroying BlueprintContainer for bundle org.apache.karaf.jaas.jasypt
[                          main] Activator                      INFO  Camel activator stopping
[                          main] Activator                      INFO  Camel activator stopped
[                          main] CamelBlueprintHelper           INFO  Deleting work directory target/bundles/1450754066802
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 11.631 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-bundle-plugin:2.3.7:bundle (default-bundle) @ camel-blueprint-encrypted ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 27.021 s
[INFO] Finished at: 2015-12-21T22:14:38-05:00
[INFO] Final Memory: 23M/442M
[INFO] ------------------------------------------------------------------------

Now you can store database, broker or API passwords in property files without them being in plaintext.

Reference Docs: Red Hat JBoss Fuse 6.2.1 Security Guide