Application Development with Encrypted Key and Trust Stores

This section describes application development requirements for users writing custom applications for encrypted key and trust stores in both FIPS and non-FIPS modes.

Support for Encrypted Key and Trust Stores

Release 7.0.0 uses Hadoop 2.7.6, so by default HADOOP_HOME is ${MAPR_HOME}/hadoop/hadoop-2.7.6.

Beginning with release 7.0.0, clear-text passwords are removed from the Hadoop ssl-server.xml and ssl-client.xml configuration files. For Java applications, key and trust store passwords are now protected in credential stores accessible through the Hadoop Credential Provider API.

Credential store provider settings differ depending on whether the node is a non-FIPS secure node or a FIPS-enabled node., due to the difference in store types. In addition, the provider settings differ depending on whether the application requiring access is a client or server application. Client applications only require access to trust stores to retrieve both keys and certificates. Server applications require access to both key and trust stores so that they can retrieve private keys as well as certificates.

Credential Provider Configuration for Client Applications

After running configure.sh, the Hadoop global configuration file ${HADOOP_HOME}/etc/hadoop/core-site.xml is configured with the location of the trust-store provider. Secure non-FIPS nodes use the JCEKS credential store type. FIPS-enabled nodes use the BCFKS credential store type. Therefore, on a secure non-FIPS node, the client-side credential provider setting in core-site.xml looks like this:
<property> 
  <name>hadoop.security.credential.provider.path</name> 
  <value>localjceks://file/opt/mapr/conf/maprtrustcreds.jceks</value> 
  <description>File-based trust store credential provider.</description> 
</property> 
On a FIPS-enabled node, the client-side credential provider setting in core-site.xml looks like this:
<property> 
  <name>hadoop.security.credential.provider.path</name> 
  <value>localjceks://file/opt/mapr/conf/maprtrustcreds.bcfks</value> 
  <description>File-based trust store credential provider.</description> 
</property> 

Credential Provider Configuration for Server Applications

For server-side custom applications using ssl-server.xml, the credential provider property is configured in ssl-server.xml itself. For a secure non-FIPS node, the credential provider setting in ssl-server.xml looks like this:
<property> 
  <name>hadoop.security.credential.provider.path</name> 

  <value>localjceks://file/opt/mapr/conf/maprkeycreds.jceks,localjceks://file/opt/mapr/conf/maprtrustcreds.jceks</value> 
  <description>File-based key and trust store credential provider.</description> 
</property> 

Using the Hadoop Configuration API

Custom client applications that need access to the trust-store password to access ${MAPR_HOME}/conf/ssl_truststore need to be enhanced to add the ${HADOOP_HOME}/etc/hadoop/core-site.xml to the Configuration resource. For example:
import org.apache.hadoop.conf.Configuration; 
... 
try { 
  final Configuration conf = new Configuration(false);  
  conf.addResource("core-site.xml", false); 
   ... 
} 
Server-side custom applications that need the key-store password to access ${MAPR_HOME}/conf/ssl_keystore need to add ssl-server.xml to the Configuration resource. For example:
import org.apache.hadoop.conf.Configuration; 
... 
try { 
  final Configuration conf = new Configuration(false);  
  conf.addResource("ssl-server.xml", false); 
   ... 
} 

Additional Requirements for FIPS 140-2 Application Development

FIPS Security Policy

The HPE Ezmeral FIPS-compliant java.security configuration is available in ${MAPR_HOME}/conf/java.security for use by Java applications. To ensure that only FIPS-compliant cryptography and security providers are used in custom Java applications, use this security file to override the master java.security file that is installed by default with JDK 11 using the java.security.properties==${MAPR_HOME}/conf/java.security.fips option. Perform this task while running your Java application in FIPS mode.

If you choose to use alternative FIPS-compliant Java security providers, Hewlett Packard Enterprise recommends that you make a copy of the configuration in java.security.properties==${MAPR_HOME}/conf/java.security.fips instead of modifying this directly. Hewlett Packard Enterprise recommends this option because the correct functionality of the HPE Ezmeral core components depend on this configuration. It is also the user's responsibility to ensure that any security providers used in a modified java.security configuration are FIPS compliant. For example:
JAVA_SECURITY_FIPS= 
# 
# Options required for running your custom Java application 
YOUR_CUSTOM_JAVA_OPTS="" 
#  
# Determine FIPS mode, and add the MAPR_ALTERNATE_JAVA_SECURITY option 
get_fips_mode=$(sysctl crypto.fips_enabled 2> /dev/null) 
fips_enabled='crypto.fips_enabled = 1' 
if [ "$get_fips_mode" == "$fips_enabled" ]; then 
 # Override the default java.security when in FIPS mode 
 JAVA_SECURITY_FIPS=-Djava.security.properties==${MAPR_HOME}/conf/java.security.fips 
fi 
# Run your custom Java application 
"$JAVA_HOME"/bin/java ${JAVA_SECURITY_FIPS} \ 
     -classpath ${YOUR_CUSTOM_CLASSPATH} com.example.yourapp $args 

Bouncy Castle FIPS Provider

For Java applications, HPE Ezmeral Data Fabric release 7.0.0 uses the Bouncy Castle FIPS Java API. The Bouncy Castle JAR files are bundled with the release 7.0.0 distribution in /opt/mapr/lib:
  • bc-fips-1.0.2.1.jar
  • bctls-fips-1.0.11.4.jar

To write FIPS-compliant Java applications using the Bouncy Castle Java FIPS API, see the Bouncy Castle FIPS Java website. For examples, see this document.

TLS Communication

For TLS communication in FIPS mode, the following changes are required.
  1. Look for the key store type in the ssl-server.xml or ssl-client.xml.
  2. For the BCFKS store type:
    1. Set the key manager factory algorithm to PKIX.
    2. Set the security provider to BCJSSE.
    3. Set the key store type to BCFKS.
    Here is an example using SslContextFactory:
    SslContextFactory.Server sslContextFactory =  
                             new SslContextFactory.Server(); 
    if (keyStoreType.equalsIgnoreCase(BCFKS_FIPS_KEYSTORE_TYPE)) { 
      sslContextFactory.setKeyManagerFactoryAlgorithm("PKIX"); 
      sslContextFactory.setProvider("BCJSSE"); 
      sslContextFactory.setKeyStoreType("BCFKS"); 
    }