Buildomatic Database Password Encryption

Disclaimer: Full password security cannot be guaranteed from within JasperReports Server. A user with sufficient privileges and knowledge of JasperReports Server can gain access to the encryption keys and the configuration passwords. While one could ask for passwords on every server restart, it is impractical for most users. The only practical way to guarantee password security is through backup and restriction of access to the keystore property file.

Introduction

In JasperReports Server v5.5 or greater, Buildomatic Password Encryption (PE) allows JasperReports Server administrators to obfuscate plain text database passwords in the configuration files. This satisfies the security audit requirements and protects the passwords from being observed by unauthorized individuals. PE happens during JasperReports Server installation. If the installation deploys to the Tomcat application server, the database password is automatically encrypted in the JNDI configuration as well (context.xml).

Buildomatic Password Encryption (PE) also lets admins encrypt certain default-master.properties. For example, quartz.mail.sender.password can be encrypted this way.

How to Encrypt Database Passwords

JasperReports Server Running on Tomcat (or Spring tcServer)

It is very easy to encrypt the database passwords in buildomatic and in META-INF/context.xml JNDI configuration. After configuring default-master.properties, you uncomment the encrypt=true property in the same file. Running js-install with encrypt set to true will replace the dbPassword property value with its encrypted equivalent. The replacement will happen in-situ and without warning. Furthermore, the JNDI password would also appear encrypted in context.xml in the new JasperReports Server instance.

Note: If your database is Oracle, you will also want to uncomment an additional property, propsToEncrypt and set it to dbPassword,sysPassword. propsToEncrypt specifies a list of the properties that should be encrypted in the buildomatic. However, for now, only database passwords are handled.

JasperReports Server Running on Enterprise Servers (JBoss, Glassfish, Websphere, Weblogic)

Unlike Tomcat, enterprise servers have proprietary ways to set up password encryption. JasperReports Server does not automatically setup encrypted passwords for them. If you require that buildomatic still be encrypted, you should follow this slightly more complicated procedure:

  1. Deploy JasperReports Server to to your enterprise server as specified in the Install Guide. The resulting JasperReports Server instance will have unencrypted JNDI datasource passwords. If you want to encrypt these passwords, refer to your application server's documentation. For example:
  2. After the server has been successfully configured, you can proceed with encrypting Jasper Server buildomatic files.
    1. In default_masper.properties, turn on encryption by uncommenting encrypt=true.
    2. Run target js-ant refresh-config, which will remove and recreate all the configuration files without deploying them to the application server. Now the buildomatic files will have the database passwords encrypted. You should still be able to execute import/export or other scripts.

Note: Do not run js-install or js-ant deploy-webapp-pro. These commands will overwrite the war file created in step 1 and render the server datasources inaccessible. If you need to redeploy the war file, reset the database password(s) to plain text and start again with step 1.

How to Encrypt Some Other Properties in default-master.properties

There are some other properties that you can encrypt in default-master.properties. Those are the properties that are loaded into Spring application context via propertyConfigurer bean in applicationContext-webapp.xml.

<bean id="propertyConfigurer" class="com.jaspersoft.jasperserver.api.common.properties.DecryptingPropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
        <value>/WEB-INF/hibernate.properties</value>
        <value>/WEB-INF/js.quartz.properties</value>
        <value>/WEB-INF/js.spring.properties</value>
        <value>/WEB-INF/js.scheduling.properties</value>
        <value>/WEB-INF/mondrian.connect.string.properties</value>
        <value>/WEB-INF/js.diagnostic.properties</value>
        <value>/WEB-INF/js.aws.datasource.properties</value>
        <value>/WEB-INF/js.config.properties</value>
      </list>
    </property>
    ...
</bean>
</pre>

Because Jaspersoft extended Spring's PropertyPlaceholderConfigurer class as DecryptingPropertyPlaceholderConfigurer, all the loaded properties are scanned for ENC- prefix and - suffix. If those markers are found around the property value, that property is decrypted before being loaded into Spring context.

To determine if your property is scanned by propertyConfigurer, you need to search if it is defined in one of the files in propertyConfigurer's locations. For e.g., say you are looking to encrypt the password property of reportSchedulerMailSender bean in applicationContext-report-scheduling.xml.

<bean id="reportSchedulerMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${report.scheduler.mail.sender.host}"/>
        <property name="username" value="${report.scheduler.mail.sender.username}"/>
        <property name="password" value="${report.scheduler.mail.sender.password}"/>
            ...
</bean>

${report.scheduler.mail.sender.password} tells you that report.scheduler.mail.sender.password is most likely defined via propertyConfigurer bean. Search through the propertyConfigurer locations to verify. You will be able to find this property defined in /WEB-INF/js.quartz.properties: report.scheduler.mail.sender.password=${quartz.mail.sender.password}.

Now, quartz.mail.sender.password property can be encrypted in default-master.properties as follows:
Set quartz.mail.sender.password with a desired password in default-master.properties: quartz.mail.sender.password=XXYYZZ. If an installation has not happened, you can uncomment encrypt=true and propsToEncrypt=dbPassword in default-master.properties. Then, you could add quartz.mail.sender.password to propsToEncrypt: propsToEncrypt=dbPassword,quartz.mail.sender.password.

quartz.mail.sender.password=XXYYZZ
encrypt=true
propsToEncrypt=dbPassword,quartz.mail.sender.password

After running js-install, verify that report.scheduler.mail.sender.password was encrypted in both default-master.properties and in /WEB-INF/js.quartz.properties.

If the installation already ran, set the properties as mentioned above and re-run it.

Note that if the properties are defined via JNDI, we recommend pointing there versus encrypting:

<property name="password”>
    <jee:jndi-lookup jndi-name="java:comp/env/emailPassword" />
</property>

Encryption Details and Options

In buildomatic, the passwords are symmetrically encrypted: the same secret key is used for both encryption and decryption. The key and its containing keystore file are randomly generated on each machine during the first JasperReports Server installation. All the subsequent JasperReports Server installations rely on the same keystore; they do not regenerate the key.

Keystore is an encrypted file that is used to securely store secret keys. To access the keystore, JasperReports Server accesses keystore properties. Both the keystore and keystore properties files are created by default in the user home directory. Alternatively, before running js-install, you can specify different locations for the keystore and keystore properties files via the environmental variables ks and ksp, respectively.

By default, database passwords are encrypted with the AES-128 algorithm in Cipher Block Chaining mode with PKCS5 padding. The AES algorithm is the current industry encryption standard. You can choose to modify the encryption strength by choosing either a different algorithm, a longer secret key size (E.g. AES-256), or a different encryption mode (although in our estimation, this is not necessary). The following properties in default_masper.properties allow you to make the mentioned changes:

Note: If the properties in the following table remain commented out, their default values are used.

Property Description Default
build.key.algo Algorithm used to encrypt the properties specified in propsToEncrypt AES
build.key.size

Size of the encryption key as in AES-128.

To increase the key size, if it has not been done before, you might have to install “Unlimited Strength Jurisdiction Policy Files” off the oracle site for your Java version. To install the files, download US_export_policy.jar and local_policy.jar. AFTER backing up the old files, extract the jars into %JAVA_HOME%/jre/lib/security directory.

Alternatively, you may download one of the reputable providers such as Bouncy Castle (ships with JasperReports Server). You would need to add the Bouncy Castle provider to to the list in %JAVA_HOME%/jre/lib/security/java.security file: security.provider.<seq number>=org.bouncycastle.jce.provider.BouncyCastleProvider

128 (bits)
enc.transformation

So called encryption mode. See Java Cryptography Extension to understand the modes and padding better.

AES/CBC/PKCS5Padding

enc.block.size The size of the block that is encrypted. Encrypted text can contain many blocks. Usually the block is changed together with the encryption algorithm. 16 (bytes)
propsToEncrypt A comma separated list of the properties to encrypt. dbPassword

Feedback