javassljettykeystoresni

Jetty Server has multiple server certificates


I want to put more than one server certificates in one Java Keystore(All have different CN). How can I config SSL so that when client specifies a hostname, the certificate with matching CN is returned, but if it's not specified, a desired default certificate is always returned.

I know that I can write my own key manager, but is there a simpler way? what is certAlias in Jetty, is it going to solve my problem?

I've seen other posts saying that the first certificate in the keystore is returned if no SNI matched. But in my case, it seems rather random, not to do with the order of certificates.

Thanks!


Solution

  • Your entire question is answered by simply using TLS + SNI properly.

    SNI (Server Name Indication) is very old, and very mature. It was first defined back in June 2003 as part of the TLS Extensions Spec RFC 3546 and has had multiple updates since then. (RFC 4366, RFC 6066, and then RFC 9325)

    All modern HTTP Clients (be it a browser, or an embedded HTTP client library) will use SNI when talking https to a server (technically, the TLS layer is handling this part). Even the venerable Java java.net.HttpURLConnection supports SNI (in reality, the Java TLS layer is doing this, the client library doesn't have to do anything extra to support SNI over TLS).

    SNI has multiple configurations in Jetty.

    org.eclipse.jetty.util.ssl.SslContextFactory.Server

    org.eclipse.jetty.server.SecureRequestCustomizer

    I would strongly encourage you to NOT replace the KeyManager with your own implementation unless you are intimately aware of the entirety of SNI and TLS both from a spec point of view, and the nuances of each of the major browsers behavior with regards to how they treat SNI (eg: local names, localhost, ip literals, non-routables, reserved hosts, protected hosts, etc).

    Start with the default behavior in Jetty (which just uses the built-in JVM techniques for working with TLS + SNI as a server), then if you have more needs in terms of how to select a certificate, look at providing your own SniX509ExtendedKeyManager.SniSelector (but make sure to keep it up to date! you'll want to follow the code of the default implementation periodically to catch changes that happen due to various factors: major browser vendor changes in behavior, JVM changes in behavior, Java crypto roadmap changes, etc)