Newer
Older
labs / tiddlywiki / tiddlers / content / labs / lab13 / _Labs_13_Transport Encryption (HTTPS).md

Note: This section should have been in last week's lab since it relates more to the web application than the database. We had some trouble working out how to create usable X.509 certificates since the mechanisms that we have used in the past no longer work due to web browsers and Java getting increasingly picky about which certificates they consider acceptable. We now have a solution to the problem, so we will cover the topic in this section.

Our web application is using plain HTTP. We need to be using transport encryption to protect the customer's details as they are travelling over the network. This is even more important since we are using Basic Access Authentication (or would be if you implemented the authentication bonus task), which means our authentication token is susceptible to hijacking via network sniffing --- any time you are using token-based authentication, you need to also be using transport encryption (there are some exceptions to this rule, but in general, authentication tokens need to be protected).

In order to use TLS (Transport Layer Security) we need to create an X.509 certificate that will be used to encrypt the HTTP messages. HTTP that is encrypted via TLS is commonly known as 'HTTPS'. Note that TLS is an evolution of SSL (Secure Sockets Layer) which has been deprecated for many years, but people still regularly refer to TLS as SSL.

The traditional way to do this during development is to create and use a 'self-signed' certificate. Once we are ready to deploy the completed system to a production server we would obtain and use a certificate that is signed by a recognised CA (Certificate Authority) and use this instead of the self-signed certificate. However, as mentioned above, browsers and server software are becoming more and more picky about the certificates that they are willing to use, so using self-signed certificates is no longer a valid option. Our only remaining option is to create and use a certificate that is signed by a CA key that is trusted by the operating system and web browsers.

Luckily, we can create our own CA certificate and signing key and register the certificate with the operating system and browsers. We can then use this CA key to sign any other certificates that we create. These signed certificates will then be trusted by the web browsers and server software, and everything should work. The process of doing all of this can be a bit tricky, but there is a tool called mkcert that does most of the work for us. You can read more about mkcert at:

https://blog.filippo.io/mkcert-valid-https-certificates-for-localhost/

Instructions:

  1. Open your project's resources folder in a terminal. The easiest way to do this is to right click <> in the <

    > pane and select <>. Then right click the background of the file manager and select <>.

  2. We have already created and installed the CA certificate on the lab machines in OBS 3.27, so all you need to do is register it with your web browsers. Run the following command in the terminal:

    mkcert -install

    This is the exact same command that we used to create and install the certificates in the rest of the operating system --- the primary difference being that we used an administrator account that was allowed to modify the system CA trust stores to do this.

  3. Restart your web browser. We have just added a new trusted CA certificate to the browser which will not be recognised until the browser is restarted.

  4. Now you need to create a signed certificate for your web server. Run the following command in the terminal:

    mkcert localhost

    Our sever is running on the localhost host, so we need to create a certificate for that host.

    We are finished with the terminal now so you can close it by entering the command exit.

  5. You should see two new files in your <> folder in the projects pane:

    • localhost.pem is the certificate for your server.
    • localhost-key.pem is the private key for your server.Although TLS is uses X.509 certificates which can be used for public key (asymmetric) encryption, TLS uses symmetric encryption. The client and server perform a handshake to negotiate a shared session key which is then used by both sides for encrypting and decrypting the messages. The private key that is generated is used as part of the handshake but is not used for the encryption of HTTP messages.
  6. We need to tell Jooby where to find the certificate and key, so add the following to the application.conf file that you created in section 3 of the previous lab.

    application.securePort = 8443
    
    application.tmpdir = build/tmp
    
    ssl {
        keystore.cert = localhost.pem
        keystore.key = localhost-key.pem
    }

    The also sets the port that will be used for HTTPS connections, and defines a temporary directory that Jooby will use to store the keys while the server is running.

  7. Run your application. You should now see two URLs being displayed in the output console when Jooby starts. Click the one that starts with https://.

    You should see the padlock icon in the browser's location bar to indicate that the connection is encrypted. Your web pages should still work as per normal.

  8. We should check that the HTTP communication is actually being encrypted. You can run a network sniffer to check this. Open a terminal and run the following command:

    tcpflow port 8080

    If your server is not running on port 8080 then change the number to match your port.

    This network sniffer will only monitor traffic on localhost and can not be used to monitor regular network traffic. It would make the ITS security staff very grumpy if we let you do that.

    This terminal will be monitoring the normal unencrypted HTTP traffic that your server is seeing.

  9. Open another terminal and run the following command:

     tcpflow port 8443

    This terminal will be monitoring the encrypted HTTPS traffic that your server is seeing.

  10. Open the normal http:// link in a browser, and register a new customer account through your web application.

    Look in the first terminal. Note that the customer's details including their password are displayed in clear text in the tcpflow output. Clearly, there isn't much in the way on encryption going on here --- everything is there to be seen by a malicious party who is sniffing the network.

  11. Repeat the process using the https:// link, and check the second terminal. You should only see gibberish in the tcpflow output. The network sniffer will still have access to the data travelling over the network, but it is now encrypted, and useless to a malicious party.

  12. You can hit < c">> to stop tcpflow, and then exit both terminals.

Note that we did not need to write any JavaScript or Java code to encrypt the HTTP request. We have added the encryption at a layer below where our application resides --- the browser and the web server are doing all of the hard work for us --- our application should not even be aware that the encryption is taking place.