2.3. Using Encrypted Property Placeholders

Overview

When securing a container it is undesirable to use plain text passwords in configuration files. They create easy to target security holes. One way to avoid this problem is to use encrypted property placeholders when ever possible. This feature is supported both in Blueprint XML files and in Spring XML files.

How to use encrypted property placeholders

To use encrypted property placeholders in a Blueprint XML file or in a Spring XML file, perform the following steps:
  1. Download and install Jasypt, to gain access to the Jasypt listAlgorithms.sh, encrypt.sh and decrypt.sh command-line tools.
    Note
    When installing the Jasypt command-line tools, don't forget to enable execute permissions on the script files, by running chmod u+x ScriptName.sh.
  2. Choose a master password and an encryption algorithm. To discover which algorithms are supported in your current Java environment, run the listAlgorithms.sh Jasypt command-line tool, as follows:
    ./listAlgorithms.sh
    DIGEST ALGORITHMS:   [MD2, MD5, SHA, SHA-256, SHA-384, SHA-512]
    
    PBE ALGORITHMS:      [PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40]
    On Windows platforms, the script is listAlgorithms.bat. JBoss Fuse uses PBEWithMD5AndDES by default.
  3. Use the Jasypt encrypt command-line tool to encrypt your sensitive configuration values (for example, passwords for use in configuration files). For example, the following command encrypts the PlaintextVal value, using the specified algorithm and master password MasterPass:
    ./encrypt.sh input="PlaintextVal" algorithm=PBEWithMD5AndDES password=MasterPass
  4. Create a properties file with encrypted values. For example, suppose you wanted to store some LDAP credentials. You could create a file, etc/ldap.properties, with the following contents:

    Example 2.6. Property File with an Encrypted Property

    #ldap.properties
    ldap.password=ENC(amIsvdqno9iSwnd7kAlLYQ==)
    ldap.url=ldap://192.168.1.74:10389
    The encrypted property values (as generated in the previous step) are identified by wrapping in the ENC() function.
  5. (Blueprint XML only) Add the requisite namespaces to your Blueprint XML file:
    • Aries extensions—http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0
    • Apache Karaf Jasypt—http://karaf.apache.org/xmlns/jasypt/v1.0.0
    Example 2.7, “Encrypted Property Namespaces” shows a Blueprint file with the requisite namespaces.

    Example 2.7. Encrypted Property Namespaces

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
     	xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
     	xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0">
    ...
    </blueprint>
  6. Configure the location of the properties file for the property placeholder and configure the Jasypt encryption algorithm .
    • Blueprint XML
      Example 2.8, “Jasypt Blueprint Configuration” shows how to configure the ext:property-placeholder element to read properties from the etc/ldap.properties file. The enc:property-placeholder element configures Jasypt to use the PBEWithMD5AndDES encryption algorithm and to read the master password from the JASYPT_ENCRYPTION_PASSWORD environment variable.

      Example 2.8. Jasypt Blueprint Configuration

      <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       	xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
       	xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0">
      
        <ext:property-placeholder>
          <location>file:etc/ldap.properties</location>
        </ext:property-placeholder>
      
        <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>
      ...
      </blueprint>
    • Spring XML
      Example 2.9, “Jasypt Spring Configuration” shows how to configure Jasypt to use the PBEWithMD5AndDES encryption algorithm and to read the master password from the JASYPT_ENCRYPTION_PASSWORD environment variable.
      The EncryptablePropertyPlaceholderConfigurer bean is configured to read properties from the etc/ldap.properties file and to read properties from the io.fabric8.mq.fabric.ConfigurationProperties class (which defines the karaf.base property, for example).

      Example 2.9. Jasypt Spring Configuration

      <bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
          <property name="algorithm" value="PBEWithMD5AndDES" />
          <property name="passwordEnvName" value="JASYPT_ENCRYPTION_PASSWORD" />
      </bean>
      
      <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
          <property name="config" ref="environmentVariablesConfiguration" />
      </bean> 
      
      <bean id="propertyConfigurer" class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer"> 
          <constructor-arg ref="configurationEncryptor" /> 
          <property name="location" value="file:${karaf.base}/etc/ldap.properties"/>
          <property name="properties">
              <bean class="io.fabric8.mq.fabric.ConfigurationProperties"/>
          </property>
      </bean>
  7. Use the placeholders in your configuration file. The placeholders you use for encrypted properties are the same as you use for regular properties. Use the syntax ${prop.name}.
  8. Make sure that the jasypt-encryption feature is installed in the container. If necessary, install the jasypt-encryption feature with the following console command:
    JBossFuse:karaf@root> features:install jasypt-encryption
  9. Shut down the container, by entering the following command:
    JBossFuse:karaf@root> shutdown
  10. Carefully restart the container and deploy your secure application, as follows:
    1. Open a command window (first command window) and enter the following commands to start the JBoss Fuse container in the background:
      export JASYPT_ENCRYPTION_PASSWORD="your super secret master pass phrase"
      ./bin/start
    2. Open a second command window and start the client utility, to connect to the container running in the background:
      ./bin/client -u Username -p Password
      Where Username and Password are valid JAAS user credentials for logging on to the container console.
    3. In the second command window, use the console to install your secure application that uses encrypted property placeholders. Check that the application has launched successfully (for example, using the osgi:list command to check its status).
    4. After the secure application has started up, go back to the first command window and unset the JASYPT_ENCRYPTION_PASSWORD environment variable.
      Important
      Unsetting the JASYPT_ENCRYPTION_PASSWORD environment variable ensures there will be minimum risk of exposing the master password. The Jasypt library retains the master password in encrypted form in memory.

Blueprint XML example

Example 2.10, “Jasypt Example in Blueprint XML” shows an example of an LDAP JAAS realm configured in Blueprint XML, using Jasypt encrypted property placeholders.

Example 2.10. Jasypt Example in Blueprint XML

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
 	xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
 	xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0">

  <ext:property-placeholder>
    <location>file:etc/ldap.properties</location>
  </ext:property-placeholder>

  <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>

  <jaas:config name="karaf" rank="200">
    <jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="required">
      initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
      debug=true
        connectionURL=${ldap.url}
        connectionUsername=cn=mqbroker,ou=Services,ou=system,dc=jbossfuse,dc=com
        connectionPassword=${ldap.password}
        connectionProtocol=
        authentication=simple
        userRoleName=cn
        userBase = ou=User,ou=ActiveMQ,ou=system,dc=jbossfuse,dc=com
        userSearchMatching=(uid={0})
        userSearchSubtree=true
        roleBase = ou=Group,ou=ActiveMQ,ou=system,dc=jbossfuse,dc=com
        roleName=cn
        roleSearchMatching= (member:=uid={1})
        roleSearchSubtree=true
    </jaas:module>
  </jaas:config>

</blueprint>
The ${ldap.password} placeholder is replaced with the decrypted value of the ldap.password property from the etc/ldap.properties properties file.