Updated 30th March 2017 to reflect updated information (see comments), add additional links and add some clarifying text about why misuse-resistance is useful.
With the impending release of the ForgeRock Identity Platform, I thought I’d spend some time writing up a few of the bits of OpenAM 14 that I was directly involved with creating. One of my last acts before leaving FR to go solo, was to put in place the first phase of modernising AM’s aging system credential encryption scheme. Before I start, I should say that this encryption scheme is not used for encrypting user passwords (which are hashed by the LDAP user store, not AM). Instead, this scheme is used for encrypting various system credentials (passwords for SMTP servers, HMAC shared secrets, etc) in the config store and in exported system configurations and in a few other places.
The original (and still default) encryption method was first mentioned in Dante’s Inferno. Actually it dates from the original iPlanet codebase from the mid-90s, and uses correspondingly ancient cryptographic algorithms (MD5 and DES). It is best to regard it as providing only limited obfuscation of credentials, rather than any true security guarantees, and the advice has always been to secure the config store by traditional means (TLS, access controls) rather than rely on this encryption. Still, we can do much better than this now, so AM 14 ships with a new AESWrapEncryption scheme that provides significantly improved security:
Update (20th April, 2017): I’ve noticed that this article gets by far the most daily hits on my blog. This worries me that people are using this code as a template for building real ECDHE key agreement, when it was only intended as a guide to the Java API. There are a lot of details in safe construction of such a protocol. More secure alternatives than to trying to roll this yourself include the various complete protocols listed at the end of the article. With that said, we’ll get back to the original article:
Diffie-Hellman key agreement (DH) is a way for two parties to agree on a symmetric secret key without explicitly communicating that secret key. As such, it provides a way for the parties to negotiate a shared AES cipher key or HMAC shared secret over a potentially insecure channel. It does not by itself provide authentication, however, so it is vulnerable to man-in-the-middle attacks without additional measures. There are several ways to provide these additional measures (e.g. signing the ephemeral public keys using a CA-issued certificate, or using a protocol like OTR), but we will not discuss them here, or go into the details of how the key agreement works. Java provides support out-of-the-box for both original discrete log DH and elliptic curve (ECDH) key agreement protocols, although the latter may not be supported on all JREs. ECDH should be preferred for any new applications as it provides significantly improved security for reasonable key sizes.
As is often the case in Java, the use of these classes can be a bit convoluted. Here we demonstrate simple Java code for ECDH key agreement on the command line. We only demonstrate ephemeral key agreement, in which the two parties generate unique public/private key pairs at the start of the protocol and throw them away once the shared secret has been negotiated. This can form the basis for perfect forward secrecy.
WARNING: the code here is not a complete security protocol and should be used for reference on the Java API only.
Every now and then I discover a new class in the Java standard library that I’ve not needed to use before. Today, that class was CopyOnWriteArrayList (or rather the CopyOnWriteArraySet wrapper). This is a good choice when implementing a set of subscribers in an observer pattern, as typically the set of subscribers doesn’t change very often but we iterate through the set regularly to broadcast events. The COW implementations are optimised for exactly this case, as the iterator only hits a volatile read rather than needing a lock.
Now that the dust has settled on the launch of Java 8, we can begin to see the benefits that all these new features will bring to those of us willing to throw off the yoke of corporate oppression and start committing lambda expressions to a “Java 5” code base. The possibilities that lambdas bring, along with default methods, and the startling addition of static methods in interfaces are real game changers. For instance, it is now possible to write an entire Java application in a single interface! Those of us who have long railed against the tyranny of a single-class-per-file can now rejoice at being able to place all of our logic in a single file, and it doesn’t even need to be a class. As you will see from this post, the future is here and it is beautiful.
There seem to be lots of new programming languages popping up at the moment. Clojure, Scala, Opa, Dart, Go, Rust, and so on. I’m always a fan of new programming languages, as I feel there is still so much untapped innovation to explore. However, it can take years, or even decades for a new language to reach commercial acceptance (a sad reality). In the meantime, mainstream languages can incorporate proven features from more experimental cousins. Java, for instance, has adopted generics and annotations, both features I have some fondness for. In the spirit of encouraging further progress I offer the following as a list of largely conservative enhancements to Java that are in keeping with it’s fundamental design as an imperative object-oriented language. I don’t wish to turn Java into Haskell, because Haskell is already good enough.