Newer
Older
labs / tiddlywiki / tiddlers / content / labs / lab13 / _Labs_13_Transport Encryption.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 x509 certificates since the previous mechanisms we have used 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 tokens need to be protected).

In order to use TLS (Transport Layer Security) we need to create an x509 certificate that will be used to encrypt the HTTP messages. 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). 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 luckily 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 projects pane and select <

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

  2. We have already created and installed the CA certificate, 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 and it 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.

  5. You should see two new files in your <> folder in the projects pane. localhost.pem is the certificate (effectively the public key) for your server, and localhost-key.pem is the key (effectively the private key).

  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
    }
  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 really 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 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 completely obscured, and useless to a malicious party.

  12. You can hit < c">> to stop tcpflow, and then close 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.