How to run a fully FIPS compliant in Spring Boot application
In this tutorial we are going to learn about running a fully FIPS compliant Spring Boot application.
Part 1: “Tomcat runs in FIPS mode”, on Ubuntu
Preface #1: Some general (yet incomplete) instructions can be found here.
Preface #2: The following requires OpenSSL with FIPS 140-2 Certified Modules. On Ubuntu these are only available for “Ubuntu Advantage Advanced customers” on Ubuntu 16.04! See here and here.
$ sudo apt install libapr1 libapr1-dev (from here, might be sudo apt install libapr1-dev libssl-dev though, see here)
Download tomcat-native-1.2.23-src from here, extract, go to tomcat-native-1.2.23-src/native/
$ ./configure --with-apr=/usr/bin/apr-1-config --with-java-home=/path/to/java-home/ --with-ssl=yes
$ make
Add -Djava.library.path=/path/to/tomcat-native-1.2.23-src/native/.libs to jvm args
add the following to your project.
import org.apache.catalina.core.AprLifecycleListener;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AprConfig {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory() {
@Override
public Ssl getSsl() {
// avoid "IllegalStateException: To use SSL, the connector's protocol handler must be an AbstractHttp11JsseProtocol subclass":
return null;
}
};
// enable APR:
factory.setProtocol("org.apache.coyote.http11.Http11AprProtocol");
AprLifecycleListener aprLifecycleListener = new AprLifecycleListener();
// will throw "FIPS was not available to tcnative at build time. You will need to re-build tcnative against an OpenSSL with FIPS." with default OpenSSL:
aprLifecycleListener.setFIPSMode("on");
factory.addContextLifecycleListeners(aprLifecycleListener);
return factory;
}
}
Part 2: “JDK uses FIPS ssl Provider”
Java uses JCE “to use stronger versions of standard algorithms”. That required to install according policy files for JDKs up to 8u161, 7u171, and 6u16; “on those versions and later the policy files are included, but not enabled by default”, while “JDK 9 and later ship with, and use by default, the unlimited policy files”.
JCE is an interface which is implemented by some “provider” (like JDBC is an interface which must be implemented). While there’s even an implementation by Oracle, there are not many FIPS compliant providers (see this list). And I found only one to claim Java 11 compatibility, which is the “Bouncy Castle Crypto API” in version 1.0.2 - currently “available for early access”, see Java FIPS Road map. So Java version is to be considered here as well (see).
Conclusion
Running a fully FIPS compliant Spring Boot application requires.
1.. some configuration (see above).
2.. An OS with FIPS compliant libraries supporting your Java version.