Security can be tricky, HTTPS and TLS no less so. There are many configuration details to be aware of, and the encryption algorithms and cipher suites are moving targets, with new vulnerabilities and fixes all the time. This example does not go into all these details, but instead shows a basic example of how to bring up a HTTPS server using a self-signed TLS 1.2 key and certificate.
The main component of Java TLS communication is the Java Secure Socket Extension (JSSE). A number of algorithms and cryptographic providers are supported. The central class is the SSLContext, supported by the KeyStore. These classes load and initialise the relevant keys, certificates, and protocols which are later used by a HTTPS server (or client). See the Oracle blog, for another brief introduction to TLS 1.2, and tips on diagnosing the communication. In particular, notice the unlimited strength implementations, which have to be downloaded separately, and copied to JAVA_HOME/lib/security.
The example below shows how the certificate and key are loaded from a Java KeyStore (.jks) file, and used to initialise the SSLContext with the TLS protocol. The SSLContext is passed to the SUN HttpsServer through a HttpsConfigurator. The HttpsServer implementation takes care of the rest, and the static file handler is the same as seen in the plain HTTP based example.
The code also includes a hard-coded generation of the key and certificate. A normal server would of course not implement this, but it’s included here to make the example self-contained and working out of the box. The following command is executed, and a Java KeyStore file containing a RSA based 2048 bits key, valid for one year. The keytool command will either prompt for name and organisational details, or these can be passed in using the dname argument. Also notice that password to the keystore and key are different. Further usage details on keytool can be found here.
Since the certificate is self-signed, a modern browser will yield a warning, and not allow the communication to continue without an explicit exception, as seen below. For the sake of this example, that is fine. If we do allow the certificate to be used, we will see that the communication is indeed encrypted, “using a strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with P-256), and a strong cipher (AES_128_GCM)”, aka “TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256”.
The two files below is all that is needed. A key and certificate is generate if not already present under /tmp/test.jks. Go to https://localhost:9999/secure/test.txt and enable the security exception to try it out. Also notice the logging in the console window of the server.