LATEST VERSION: 4.0 - RELEASE NOTES
Pivotal tc Server v4.0

Encoding Properties

Obfuscating Passwords in tc Runtime Configuration Files

Pivotal tc Runtime stores its configuration files in the CATALINA_BASE/conf directory. The directory includes the following files:

  • context.xml
  • jmxremote.password
  • server.xml
  • web.xml

By default, passwords in these files are in cleartext. This is typically not a problem during development; however, when you move to production, you will probably want to protect these passwords for security reasons so that the actual password string does not show up in the configuration files.

Passwords appear in these configuration files in a variety of places. For example, as described in Configuring the High Concurrency JDBC Connection Pool, you use the <Resource> element of the server.xml file to configure a JDBC connection pool, and the element’s password attribute specifies the password of the user who connects to the database server, as shown in the following sample snippet of the server.xml file (only relevant parts shown):

<?xml version='1.0' encoding='utf-8'?>
<Server port="-1" shutdown="SHUTDOWN">
 ...
  <GlobalNamingResources>
       <Resource name="jdbc/TestDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="root"
            password="mypassword"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/mysql?autoReconnect=true"
        ...
  </GlobalNamingResources>
  ...
  <Service name="Catalina">
  ...
  </Service>
</Server>

Another example is the jmxremote.password file that contains the password for the JMX username/role that a monitoring client uses to connect to the JMX server associated with the tc Runtime instance. By default, the password is in cleartext. The following example shows the out-of-the-box file in which the admin role has the password pivotal:

# The "admin" role has password "pivotal".
admin pivotal

The remainder of this section describes how to protect the password text in any of the tc Runtime configuration files located in the CATALINA_BASE/conf directory.

Encoding a Password

As of tc Server 3.2.0, the tcserver script has an encode option that simplifies the basic usage of our PropertyDecoder as described below.

Usage of the command is as follows:

tcserver encode <value> <passphrase>

Where

  • <value> is the value such as property value to encode. If special characters such as “$” are used they should be escaped with a “\” character.
  • <passphrase> is the secret passphrase or key to use to encode the value. This value becomes a java UTF-16 encoded string of characters each consisting of 16 bytes. Because of the UTF-16 encoding there is an additional 2 bytes (16 bits) at the beginning of the string. The default JCE Jurisidiction Policy allows for 128 bit passphrases. This means that the default passphrase can be no longer than 7 characters. If special characters such as “$” are used they should be escaped with a “\” character.

The command will output an encoded value which can be used in one of the supported configuration files described in this section.

Example

tcserver encode foobar mypassphrase 2kiFLxKkcQp6PNJCryL+fublW4Q8929ZqY3bY2asJnk=

The “encode” command also supports decoding an encoded value with a known passphrase.

tcserver encode --decode <encoded value> <passphrase>

Where

  • <encoded value> is the encoded result of a previously encoded value
  • <passphrase> is the passphrase used to encode the value

Example

tcserver encode --decode 2kiFLxKkcQp6PNJCryL+fublW4Q8929ZqY3bY2asJnk=  mypassphrase
foobar

Notes

  • By default /dev/random is used on Linux for randomness. In some cases this may cause the command to take a long time to complete. It is possible to override the java default by specifying the java.security.egd property. See the example below
JAVA_OPTS=-Djava.security.egd=file:/dev/./urandom tcserver encode foo bar

PropertyDecoder Usage

In tc Server 3.0.x, and 3.1.x you are required to invoke a java command specifying classpath for needed jars and properties for the encoder to use.

Basic Encryption Usage

The following example will encrypt <valueToEncrypt> using the <passphrase>. The command uses all the default system properties for the PropertyDecoder class. It assumes that the current working directory is the instance home directory. You must specify catalina.home directory (i.e. tomcat-8.5.9.B.RELEASE).

From the Pivotal tc Server installation directory:

java -cp ":lib/*" com.springsource.tcserver.security.PropertyDecoder -encode <passphrase> <valueToEncrypt>

This command will provide an encrypted value. This value is used as a property value in catalina.properties.

Note: The length of the passphrase is controlled by the JSE Security Policy. JVM installations without JSE Unlimited Strength Policy files are limited in the length of the passphrase which is 7 characters maximum.

Advanced Encryption Usage

If you require finer grain control over the encryption method used to encode a value you may define the com.springsource.tcserver.security.PropertyDecoder.iterations. You must specify catalina.home directory (i.e. tomcat-8.5.9.B.RELEASE).

From the Pivotal tc Server installation directory:

java -cp ":lib/*" com.springsource.tcserver.security.PropertyDecoder -encode <passphrase> <valueToEncrypt>

Using a different provider

Under the hood tc Server’s encoding technology uses jasypt (external link) with the org.jasypt.encryption.pbe.StandardPBEStringEncryptor class. In theory any Provider class supported by StandardPBEStringEncryptor may be used. However, tc Server is only tested with BouncyCastleProvider.

There are two properties which can be defined that allow overriding the default Provider

  • com.springsource.tcserver.security.TcDecoder.provider - The full name of the Provider class.
  • com.springsource.tcserver.security.TcDecoder.classpath - Classpath for the provider, not needed if using BouncyCastleProvider or one contained in the JVM.

These properties need to be set in both the catalina.properties and on the command line to encode the values.

Note: At this time tcserver encode and tcserver decode do not support custom providers

The following is an example command line to encode value using passphrase with the SunJCE provider and PBEWithMD5AndTripleDES algorithm

java -cp ":lib/*" -Dcom.springsource.tcserver.security.TcDecoder.provider=com.sun.crypto.provider.SunJCE -Dcom.springsource.tcserver.security.TcDecoder.algorithm=PBEWithMD5AndTripleDES com.springsource.tcserver.security.PropertyDecoder -encode passphrase value

Properties

This table explains the properties which may be defined during the encoding/decoding process:

Name Default Description
com.springsource.tcserver.security.TcDecoder.algorithm PBEWITHSHA256AND 128BITAES-CBC-BC Sets the encryption algorithm to use
com.springsource.tcserver.security.TcDecoder.iterations 1000 Sets the number of iterations to use for encryption
com.springsource.tcserver.security.PropertyDecoder.passphrase n/a Defines the passphrase to use to decrypt the value. When the value “console” is specified the user will be prompted for the password. If using "console” the instance must be started in the foreground. See full description in section above.

Being Prompted for the Passphrase When you Start the Instance

Storing the passphrase and encrypted passwords on the local file system when using passphrase encryption is reasonably secure. However, some users may want to be prompted for the passphrase so that it does not appear in cleartext in any file at all.

Warning: This feature requires that you start the tc Runtime instance as a foreground process using the run option of the tcserver script on both Unix and Windows. On Unix, you can then put the process in the background. On Windows, however, this means that you cannot control the instance using the Windows Services console. For this reason, this feature is not practical for production use on Windows.

The following assumes that you have already generated an encoded value as described in Basic Encryption Usage and that you added it to your configuration file.

To be prompted for the passphrase when you start the tc Runtime instance, update the catalina.properties file and set the com.springsource.tcserver.security.PropertyDecoder.passphrase property to the value console.

For example (catalina.properties):

org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
com.springsource.tcserver.security.PropertyDecoder.passphrase=console
db.password=tcEnc://koBC0uF1N200plwJgBfeQg==

Storing Passphrases and Encrypted Properties in Separate Files

Although storing the passphrase (when using passphrase encryption) and encrypted passwords in the catalina.properties is reasonably secure, some users might prefer to store these values in separate files.

To store the passphrase in a separate file, replace the value of the com.springsource.tcserver.security.PropertyDecoder.passphrase property with the name of a file. You can use the ${catalina.base} variable to specify a directory relative to the CATALINA_BASE of the tc Runtime instance.

In the following sample snippet of catalina.properties, the passphrase is stored in a file called secure.file in the CATALINA_BASE/conf directory of the tc Runtime instance:

org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
com.springsource.tcserver.security.PropertyDecoder.passphrase=${catalina.base}/conf/secure.file
db.password=tcEnc://koBC0uF1N200plwJgBfeQg==

Create the secure.file file: it should contain a single line with the passphrase. For example:

mypassphrase

Similarly, to store the actual encrypted password in a separate file, replace the password variable (db.password in our example) in the catalina.properties file with a property called com.springsource.tcserver.security.PropertyDecoder.properties. Set this property to the name of a file that contains the password variable.

In the following sample snippet of catalina.properties, the encrypted password is stored in a file called application.properties in the CATALINA_BASE/conf directory of the tc Runtime instance:

org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
com.springsource.tcserver.security.PropertyDecoder.passphrase=${catalina.base}/conf/secure.file
com.springsource.tcserver.security.PropertyDecoder.properties=${catalina.base}/conf/application.properties

Create the application.properties file and add the original password variable. Following with our example, the file would include the following:

db.password=tcEnc://koBC0uF1N200plwJgBfeQg==

Example

This is a real world walk through of all the necessary steps to utilize encrypted password values. This example assumes there is a tc Runtime instance by the name of "example” and that we want to encrypt the password "catspaw” and that the "java” command is in the PATH variable. Our passphrase is "lucky77”.

The first thing to do is to change the current working directory (CWD) to the base directory of the tc Server Installation.

$ cd $TCSERVER_HOME

Next we want to tell PropertyDecoder to encode our password "catspaw”.

$ java -cp ":lib/*" com.springsource.tcserver.security.PropertyDecoder -encode lucky77 catspaw
Feb 4, 2016 9:53:46 AM com.springsource.tcserver.security.TcDecoder initCiphers
INFO: Initializing ciphers
tAAcYgb0BBg89Ms2xOCFEUqPXQgw0kFTuGXHJMbAQ1k=

The command outputted "tAAcYgb0BBg89Ms2xOCFEUqPXQgw0kFTuGXHJMbAQ1k=” this is our encrypted version of "catspaw.” This value will be different each time the same command is executed. Therefore, your encrypted value will be different. Here’s the same command executed a second time.

$ java -cp ":lib/*" com.springsource.tcserver.security.PropertyDecoder -encode lucky77 catspaw
Feb 4, 2016 9:56:54 AM com.springsource.tcserver.security.TcDecoder initCiphers
INFO: Initializing ciphers
l9IILG3R5Z5xLiKVWvqlF0qlQ28iG1W6kZ6y6mi9upQ=

The second invocation returned "l9IILG3R5Z5xLiKVWvqlF0qlQ28iG1W6kZ6y6mi9upQ=” both of these values represent an encrypted form of "catspaw.” They both may be decoded using the same passphrase.

Here we see what happens when we decode the different encrypted values.

$ java -cp ":lib/*"com.springsource.tcserver.security.PropertyDecoder -decode lucky77 tAAcYgb0BBg89Ms2xOCFEUqPXQgw0kFTuGXHJMbAQ1k=
Feb 4, 2016 10:00:52 AM com.springsource.tcserver.security.TcDecoder initCiphers
INFO: Initializing ciphers
catspaw

$ java -cp ":lib/*" com.springsource.tcserver.security.PropertyDecoder -decode lucky77 l9IILG3R5Z5xLiKVWvqlF0qlQ28iG1W6kZ6y6mi9upQ=
Feb 4, 2016 10:00:52 AM com.springsource.tcserver.security.TcDecoder initCiphers
INFO: Initializing ciphers
catspaw

Both values decrypted to "catspaw.”

Next we need to place the encoded value into <instance-home>/conf/catalina.properties. The value needs to have the special prefix "tcEnc://” added to it. This is what indicates that it is an encoded value. We also need to tell PropertyDecoder where to find the passphrase and to make sure that PropertyDecoder is being used to read the properties.

# Tell Tomcat’s digester which class to use to read properties.
org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
# Tell PropertyDecoder where to look for the passphrase
com.springsource.tcserver.security.PropertyDecoder.passphrase=${catalina.base}/conf/secure.file
# Encrypted Passowrd
db.password=tcEnc://l9IILG3R5Z5xLiKVWvqlF0qlQ28iG1W6kZ6y6mi9upQ=

The file <instance-home>/conf/secure.file should contain only "lucky77” and no other data including newlines and whitespaces.

At this point the tc Runtime instance may be started via the standard method and should read the passphrase from <instance-home>/conf/secure.file and decrypt the property "db.password” and connect properly to the DB. If there is a failure it should be logged in the catalina.log for the instance.

PBKDF2 Encoding

This feature is new in 3.2.10.RELEASE and 4.0.1.RELEASE

This section describes how to use PBKDF2 based encoding. This is a new feature introduced in 3.2.10.RELEASE and 4.0.1.RELEASE.

It uses a different prefix than the above section for property values and can not be mixed with tcenc:// (TcDecoder) encoded values.

Basic Usage

At this time tcruntime-admin.sh encode does not support this feature. To create an encoded value the following java command must be executed

java -cp ":lib/*" -Dcom.springsource.tcserver.security.PropertyDecoder.decoder_prefix=pbkdf2:// com.springsource.tcserver.security.PropertyDecoder -encode "the-key" value

This will produce the output similar to the following (the last line will be different)

Apr 17, 2018 10:49:01 AM com.springsource.tcserver.security.PBKDF2Decoder <init>
INFO: Initializating PBKDF2Decoder
8M3+OyGseovqPxv+3s0x+cUwFq4V3fYWO9ldsNNm4/DWsRv0n6M659+ScSxgH2W3wXs5OdNfGGAFh93k9uNjh6NAnAJousuEoo+76gU=

Similarly to the other encoding method you must modify catalina.properties and add the following:

com.springsource.tcserver.security.PropertyDecoder.decoder_prefix=pbkdf2://
com.springsource.tcserver.security.PropertyDecoder.passphrase=the-key

Installing JCE Unlimited Strength Jurisdiction Policy Files

The default JCE Policy files limit the passphrase/key size for encoding. Under most circumstances this is sufficient. However, if larger key sizes are required the JCE Unlimited Strength Jurisdiction Policy Files may be installed.

  1. Download the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files from Oracle or IBM.
  2. Uncompress and extract the downloaded file. The download includes a Readme.txt and two .jar files with the same names as the existing policy files.
  3. Locate the two existing policy files:
    • local_policy.jar
    • US_export_policy.jar
  4. On UNIX, look in <JAVA_HOME>/lib/security/
  5. On Windows, look in C:/Program Files/Java/jre/lib/security/