Transport Layer Security

Transport Layer Security (TLS) is a standard used to encrypt network communication. The predecessor is Secure Sockets Layer (SSL).

TLS uses public-private key cryptography during a handshake in which everyone sees the public key and can encrypt messages using this public key, but only the owner of the private key (the server) may decrypt such messages. This key exchange process is called asymmetric encryption and is relatively slow. The encrypted handshake is used to agree on a shared, secret key which each side then uses to encrypt and decrypt the messages after the handshake. This is called symmetric encryption which is relatively faster. The combination of the asymmetric handshake algorithm and symmetric data encryption algorithm is called the cipher suite and the suite used must be agreed upon during the handshake.

RSA Key Exchange

One side, the server, generates a private and public key certificate pair. When the user starts a handshake with the server (e.g. a user's browser going to a website), the user sends a randomly generated number ("client random") and the server responds with the public key and its own randomly generated number ("server random"). The user encrypts a randomly generated number ("premaster secret") with the public key and sends it to the server. The server uses its matching private key to decrypt the premaster secret. The user and server independently use the premaster secret, the "client random," and "server random" numbers to generate a shared key ("session key") which is then used during symmetric encryption.

Ephemeral Diffie-Hellman Key Exchange

One side, the server, generates a private and public key certificate pair. When the user starts a handshake with the server (e.g. a user's browser going to a website), the user sends a randomly generated number ("client random") and the server responds with its own randomly generated number ("server random") along with a message encrypted using its private key that contains the Diffie-Hellman (DH) parameter, the client random, and the server random. The user decrypts the message using the public key and sends back its own DH parameter. The user and server independently calculate the premaster secret using the DH parameters. The user and server independently use the premaster secret, the "client random," and "server random" numbers to generate a shared key ("session key") which is then used during symmetric encryption.

Certificates

TLS certificates are represented using the X.509 ASN.1 DER format. Common file formats are:

  • .pem (RFC 1422): Base-64 encoded PEM format with public and/or private keys.
  • .cer, .crt, .cert, .key, and .der: Same as .pem although it may be binary encoded instead of Base-64.
    • Convert into PEM:
      openssl x509 -inform der -in in.der -out out.pem
  • .p12 (RFC 7292): Encrypted, binary encoded PKCS#12 format with public and/or private keys.
    • Convert public key into PEM:
      openssl pkcs12 -in in.p12 -nokeys -clcerts -out out.pem
    • Convert private key into PEM:
      openssl pkcs12 -in in.p12 -nocerts -out out.pem
  • .jks: Java format for public and/or private keys.
    1. Convert into PKCS#12:
      $JAVA/bin/keytool -importkeystore -srckeystore in.jks -destkeystore out.p12 -deststoretype PKCS12
    2. Convert into PEM

There are also .pub files which are public keys but not in an X.509 ASN.1 DER certificate form.

Keystores and Truststores

A keystore is a file that stores one or more certificates (keys). Formats for keystores include PKCS12, JKS, etc.

A truststore is also a keystore but it's an informal name for a keystore that a client uses to signify which certificates are trusted, such as when making outbound TLS calls.

keytool

The keytool command is part of the JDK, so if it's not on your PATH, you can find the tool inside the JDK and execute it directly. keytool is generally used to manipulate JKS keystore. Note that starting with Java 9, the JDK can read PKCS12 keystores directly in addition to JKS keystores.

Create JKS keystore from a host and port

  1. Download the certificate of your of the host and port into a temporary file. Replace localhost:443 with the host and port.
    keytool -printcert -sslserver localhost:443 -rfc >tempfile
  2. Create a JKS keystore based on this tempfile certificate. keytool requires a password.
    keytool -import -alias truststore -keystore truststore.jks -file tempfile
  3. Delete the tempfile:
    rm tempfile

If this is a truststore with public keys and the security of the truststore is not important, this may be combined in a single line with the password:

keytool -printcert -sslserver localhost:443 -rfc | keytool -import -noprompt -alias truststore -keystore truststore.jks -storepass password

List JKS keystore certificates

keytool -list -keystore truststore.jks

Use a global JKS truststore in a Java program

java -Djavax.net.ssl.trustStore=truststore.jks -Djavax.net.ssl.trustStorePassword=Password