Thursday, June 22, 2023

TLS, FIPS and the Bouncy Castle Certified Encryption Module

Image Courtesy of Wikipedia
History

Becoming educated in a topic seems to offer opportunities to become yet further educated, or in other words, once you've demonstrated expertise in a particular technology, more problems related to it will come your way.  So be careful what you work on.

Many years ago, I had to work out how to implement the IHE ATNA profile.  I spent quite a bit of time on this project and became rather expert at diagnosing TLS problems, and configuring Tomcat to support the IHE Audit Trail and Node Authentication Profile (ATNA).  So much so that I first wrote on my experiences in the IHE ATNA FAQ.

Java, has come quite a ways since then.  When the ATNA FAQ was originally written, I think I was using JDK 1.4 or 1.5, which did not have great support even for TLS 1.0.  Now Java is has cranked JDK versions past 11 all the way to 21.  Although, for reasons I will explain below, mine only goes to 11 for this post (I do use JDK 17 for other development).

TLS has also come a long way, releasing new versions, first 1.1, then 1.2, most currently 1.3, and I'm damn near certain there will be a 1.4 and maybe even a 1.5.  Many a system supports TLS.  But often, when working for large corporations or government agencies, you need to go even further, using a NIST Certified FIPS implementation of TLS.  That's one of the problems I've had to work with a team to solve.

Problem Statement

I'm presently embarked upon completely integrating FIPS certified encryption into a Java application that I'm working on (it's already integrated for inbound and outbound communications, this is for other uses).  That application runs on JDK 11 in a Spring Boot 1.5 Java application running inside an Alpine Linux based Docker container, and had already used Bouncy Castle for its crypto activities. Getting all the details right in that environment is a tricky prospect, as I will explain in later posts.  This is just the intro so that folks can understand a bit more about the requirements to be met.

Bouncy Castle

Anyone who does anything with Java and TLS probably is familiar with the Legion of the Bouncy Castle (BC) Crypto libraries.  And if you've been doing Health Information Exchange development work, you are also likely to be aware of NIST FIPS 140-2.  Some of you may even have used BC in FIPS compliant mode (or perhaps had to enable FIPS on your Windows Servers or elsewhere in Java code).  

I haven't seen a lot of attention on using FIPS certified encryption (except in AWS or Azure's Government Cloud environments), and less so in pure Java software implementation. The point of using a certified encryption module is to be sure that the encryption is secure, and the point of having a FIPS compliant mode is to ensure that other insecure encryption capabilities cannot be used.  These are essential requirements in a system where the potential impact to confidentiality, integrity or availability is of at least moderate concern. In healthcare, I believe we'd all agree that it's at least that important when exchanging healthcare data.  And also, there's a federal standard for the term "moderate", as found in the lesser known FIPS 199.

The straight BC libraries, while supporting encryption, aren't NIST Certified Modules.  That's an extra step that requires testing from NIST NVLAP certification laboratories, much like ONC Certification is also performed by accredited laboratories.  Instead, you have to use the FIPS Certified versions of the Bouncy Castle Libraries.  These libraries are largely compatible with the non-certified libraries, but are missing some capabilities those libraries have, frankly because those capabilities aren't certifiable.  They support encryption certainly, but may use ciphers that aren't considered to be secure.

The BC FIPS libraries are currently NIST certified for up to JDK-11.  If you look at BC's roadmap for FIPS certified modules you will see that the first BC FIPS release supporting JDK versions higher than 11 are 1.0.2.4, and 2.0, and those should both support JDK 17.  The 2.0 stream is being submitted through testing using FIPS 140-3, while 1.0.2.4 is tested under FIPS 140-2 requirements.  The first NC FIPS 1.x release that will be tested under 140-3 will be 1.0.3.  While FIPS 140-2 is still the minimum requirement for many government agencies (for those classified as FIPS Moderate), those agencies will require FIPS 140-3 certified modules in the near future.  After 2026, there won't be any FIPS 140-2 certified products (the certification expires), and any new products are now being certified are currently being certified under FIPS 140-3.

Bouncy Castle FIPS modules are freely available for download via Maven, but the latest and greatest code bases are only available to support contract holders.

There are other suppliers of NIST Certified encryption modules for Java, but the Legion of the Bouncy Castle is probably the most widely known, and has the broadest use by other respected software providers (e.g., RedHat, Oracle, and many others).  Some Java implementations rely on OpenSSL, another widely known crypto package.  I prefer to stick with pure Java solutions when I can, so OpenSSL is not my most favorite option.  It's also difficult to configure in Tomcat (which isn't to say that Bouncy Castle is easy, just not as hard).

Now that I've bored you to tears with the requirements that I have to work with, and the solution that was selected (BC-FIPS), later posts will talk more about the implementation details, so that maybe more Java based Healthcare IT applications will take on this prospect.  It would be nice if someday all encryption in Health IT was done by encryption modules that were rigorously tested and which refused to implement insecure protocols (such as SSL, TLS 1.0 or 1.1).  But until implementing such encryption is a LOT easier in Java (and other) applications, that's going to be a hard row to hoe.


0 comments:

Post a Comment