HTTPS support in Vert.x

Vert.x provides support for SSL-encrypted network connections. It is common to expose HTTP servers in production through a front HTTP server / proxy like Nginx, and have it use HTTPS for incoming connections. Vert.x can also expose HTTPS by itself, so as to provide end-to-end encryption.

Certificates can be stored in Java KeyStore files. You will likely need a self-signed certificate for testing purposes, and here is how to create one in a server-keystore.jks KeyStore where the password is secret:

  1. keytool -genkey \
  2. -alias test \
  3. -keyalg RSA \
  4. -keystore server-keystore.jks \
  5. -keysize 2048 \
  6. -validity 360 \
  7. -dname CN=localhost \
  8. -keypass secret \
  9. -storepass secret

We can then change the HTTP server creation to pass a HttpServerOptions object to specify that we want SSL, and to point to our KeyStore file:

  1. HttpServer server = vertx.createHttpServer(new HttpServerOptions()
  2. .setSsl(true)
  3. .setKeyStoreOptions(new JksOptions()
  4. .setPath("server-keystore.jks")
  5. .setPassword("secret")));

We can point a web browser to https://localhost:8080/, but since the certificate is a self-signed one any good browser will rightfully yield a security warning:

invalid cert

Last but not least, we need to update the test case in ApiTest since the original code was made for issuing HTTP requests with the web client:

  1. webClient = WebClient.create(vertx, new WebClientOptions()
  2. .setDefaultHost("localhost")
  3. .setDefaultPort(8080)
  4. .setSsl(true) (1)
  5. .setTrustOptions(new JksOptions().setPath("server-keystore.jks").setPassword("secret"))); (2)
  1. Ensures SSL.

  2. Since the certificate is self-signed, we need to explicitly trust it otherwise the web client connections will fail just like a web browser would.