Tuesday, 15 October 2013

SSL/TLS for Developers or IT Admins

TLS, do I care?

BEAST attacks, dodgy RC4 algorithms, government spying etc. etc. etc. SSL (or TLS as it should now be known) is quickly becoming big news. It is one of the technologies that in the past, we were happy enough for it just to work, but now we are told it is very easy to mis-configure and like many technologies must be renewed over time as older mechanisms become vulnerable to attacks.

Do I Even Need It?

This is a fair question but for many situations, the answer is a simple, "yes". Setting up TLS is not very difficult and the prices of certificates are cheap (unless you self-sign which is free!). Unless the data you are sending and receiving is completely public already and no authentication is taking place, you should probably use it.

Traditional views about the burden of SSL are largely irrelevant on todays machines, except the most fragile units like mobile phones, and I read the other day that Google's average CPU load went up by a mere 1% when SSL was enabled for all gmail accounts.

So What Is It?

If you want to encrypt your data, you are trying to prevent anyone who doesn't have the "key" from knowing what the data is in its "plain text" form. This is fine if you are sending encrypted data between two pre-established points, which can already have agreed on a key but for many situations where there are many users and most or all of these are not known to the web application, it is both impractical but also insecure to distribute the key to all of these people in advance. What TLS does is provide a mechanism that allows for a client to agree on a key to use with the server and afterwards to use this key for the entire session. This key will not be the same as the key for any other client and will not be the same one used if the client comes back another time to connect to the server.

If you are interested, wikipedia has a whole load of documents describing how this takes place, starting here: http://en.wikipedia.org/wiki/Transport_Layer_Security. We will cover how the basics work.

Secrecy and validity

The first important question is how the client establishes that it is indeed talking to who it thinks it is. It does not want to agree encryption keys with a spy server pretending to be the real server. For this, we have the whole Certificate Authority scheme which is a hierarchy of Trusted certificate issuers who basically use a secure system to assure you that if a certificate claims to be from domain xyz.com, then the server really is xyz.com because theoretically, no-one else would be able to sign a certificate claiming to be from xyz.com. Sadly, this is not actually true, since any trusted issuer can issue a certificate for any domain, which is great for competition but not so great for security. If someone steals a signing key from one of these companies (or someone bad works there) then fraudulent certificates can be generated. Currently, the only way to prevent this is to do some kind of pinning of certificates to the issuer that is known to have issued them. We won't discuss this further since the proposed solutions are not widely adopted.

Once the client sees a certificate claiming to be from xyz.com and decides it can trust this certificate, it can then use the public key contained in the certificate (which is a slow encryption method called asymmetric encryption) to encrypt some data and send it back to the server. The server can only decrypt this with its private key. Even if someone stole the certificate, without the private key they could not determine what this data is. This data is used to encrypt some other data and send it back to the client to prove that the server did receive and decrypt the data from the client - the circle is complete.

What happens next is that the client can send a list of TLS protocols that it supports to the server and the server can choose one of these to decide the details of the rest of the handshake and the methods used to encrypt the session keys. Usually, it will choose the first one in the list it supports.

Once the session keys have been generated and established at both ends, the client and server can now start using symmetric encryption which is much faster - the overhead is not noticeable except at very high server levels.

At the end of the session, one or both parties can signal to the other that the connection needs to be torn down, at which point, the machines can clean up their encryption keys.

Setting It Up

Setting up TLS is pretty easy, certainly on Apache, nginx and IIS. In IIS, for instance, you can request a certificate within the GUI, which produces a request file. This file is sent to a certificate issuer who will give you a certificate from as little as $10 (free from some places if you are not-for-profit), which you then add back into IIS with the click of a mouse. At this point, you can enable SSL for a given website, add the binding to port 443 (or whichever) and then tell it which certificate to use.

Apache and nginx are pretty similar but mostly done in the configuration file, pointing to the locations of the certificate files.

If you only did that, you would get a system that works, that gives you a green padlock and a warm fuzzy feeling that you are nice and secure so what's the problem?

Configuration and Weaknesses

There are some problems with these default setups. Some of it is understandable, other parts are suspicious, all of it should be checked and as a developer (or an IT admin), you should be familiar with the latest issues found in SSL and various algorithms therein. You should also be aware that some tools are very useful for helping you but others might also give false positives or false negatives so try and cover as much as possible and record what you know.

There is a difference between locking down systems where you have control over both ends (a mobile app connecting to your web server) as opposed to websites that you want to reach as many people as possible. TLS provides a big headache when it comes to older browsers and we will see why.

The main areas of issue are the relative weaknesses of TLS algorithms (sometimes vs speed) and the weakness in some libraries to correctly handle the SSL handshake and verification of Certificates. A very useful tool can be found here: https://www.ssllabs.com/ssltest/ which will connect to the specified server and check for known issues, spelling them out in useful detail. You are unlikely to score more than 90s across the board unless it is your own server but this is usually at the cost of older browsers not being able to connect (including newer versions of FireFox and IE!).

The History Weaknesses

History provides weaknesses in certain ways. As you might imagine, although TLS version 1.2 is reasonably well understood, many browsers either do not support it at all, or more confusingly do not have it enabled by default. For this reason, your servers must still support TLSv1 (and 1.1) and this, although reasonably secure, is certainly not ideal.

History has also shown that certain algorithms are no longer secure enough, perhaps just because they are old (and key lengths need to increase to make them harder to brute force) or because time has revealed weaknesses which can be exploited. Although most servers allow you to configure which algorithms you support, usually, the ordering is not definable since the client tells the server which algorithms it supports in order of preference. These also need to be balanced with the fact that you may need to support older algorithms for older browsers. By supporting older algorithms, even if the order puts the best ones first, it is sometimes possible for an attacker to force the client and server to both downgrade their algorithm to a weak version which can more easily be hacked or exploited. The general instruction here is to put the strong ones first (DHCE and DHE) and some middle-ones afterwards that are reasonably strong and not to include any of the most weak versions - ones that use things like MD5 hashes. (There are various articles on Google about which to use)

The third way in which history hurts is that the longer that these have been exposed to the wild west of the internet, the longer attackers have had to try and exploit them, in which case certain modes like block chaining and RC4 encryption have supposed weaknesses that mean that although these attacks might be unlikely or hard, these systems are worth avoiding.

The Trade-off Weakness

Another type of weakness relates to the fact that some algorithms are much slower than others for given key sizes. This means that although a client might want a strong algorithm, a server is more likely to prefer one that is faster, even if a little less secure. The advice here is to start with the strong ciphers and worry about the performance when it becomes a problem. Load-test the systems to compare different ciphers before making the systems weaker.

Client Weaknesses

Client weaknesses fall into two camps. The browser weaknesses, the most common method used to connect to web applications, but also any net-aware client applications, assumed to be written in-house but the same issues apply anyway.

For a browser, your hands are tied. Unless you are one of the open-source browser developers, you have limited control over what is enabled/disabled, what cipher suites are supported, which are preferred and how well they are implemented. The plus-side is that the weaknesses are usually well known and well documented. Another issue with browsers is that you have no control over older versions that still exist and from which you might well want people to still connect to your system. Forcing people to update browsers is not easy, even if they are direct customers. The advice, know the limits of each browser, have an idea of which older versions you won't support (based on usage stats) and keep aware of the latest changes. Once a good percentage of browsers support, for instance, TLS 1.1, you might disable TLS 1.0. Also, try and capture browser stats for your own sites. General browser stats are handy but it is better know what your users connect with to decide how many will be affected by tightening anything up.

Client apps (and net-aware mobile apps) suffer the same potential problems as browsers but these should be more within your control. The following section discusses certain things that you should check before you trust these apps to communicate effectively.

Client App Weaknesses

Like most developers, I found a library for my Android app (The Apache HttpClient library), plugged it in and away I went. There are, however, a whole load of assumptions I have made about this library which I have not currently checked but definitely should.
  1. Does the library check that the host name on the SSL certificate matches the host name I am using the client to connect to?
  2. Do I get an error if the certificate is self-signed?
  3. Do I get an error if the chain of trust cannot be established on the SSL certificate?
  4. If I revoke a certificate, will the library ever detect this and block the connection? If so when?
  5. What cipher suites does the library send to the server and in what order? How can I limit this, especially if I only talk to my own servers?
  6. What protocol version does it use by default and which does it support? SSL? TLS 1.0? TLS 1.2?
  7. Does the library correctly implement security features such as blocking client renegotiation?


TLS is a minefield but although it is quite a large field, fortunately, the information is all there on the net to make informed decisions. Sites like stackoverflow or serverfault are frequented by clever people. The Qualsys site is fantastic for the latest best-practice, and the people who run the lab are very active on the forums there.

Spend some time learning about how TLS hangs together and remember, most of the time, something is better than nothing. Start with the first steps and try and test and fix as time goes by so that at least your system will be hard enough to crack, which will cause the attackers to try somewhere else instead!
Post a Comment