There seems to be a lot of misunderstanding about Web Service security. Using password authentication doesn’t prevent unauthorized users to access your data, while SSL / HTTPS doesn’t give you any information about who is trying to access your services. And did you ever think of signing you messages with a digital signature?
In my introductory post I’ve elaborated on what type of security we’d typically want on Web Services.
In part 1 , I’ve dealt with Username Token authentication.
In this article, I will describe Transport Level Security (TLS), formerly known as Secure Socket Layer and message encryption.
Lets recap the security requirements I have discussed in my introduction.
The client must be sure it sends it messages to the correct provider;
The provider wants to be sure that the client is authorized to;
The provider wants to be sure that the client is who it says it is;
Both the consumer and provider want to be sure that the messages can only be interpreted by each other;
Both parties want to be sure that the message sent is received unchanged.
Transport Level Security
Using “Transport Level Security” (TLS), formerly known as Secure Socket Layer (SSL), and also referred to as HTTPS, will take care of requirements 1 and 4.
TLS is a technically very complex algorithm, with a lot of varieties. Fortunately, the general concept is not as hard to grasp. It works as follows:
The client will send a “Hello” to the server.
The server will response with a “Hello”, and send a certificate to the client
The client will decide whether it trusts the server’s certificate
The client will use the servers certificate to encrypt its own certificate and send it back to the server
Depending on the exact algorithm chosen, the client and server will exchange some more encryption information to make the communication “water tight”.
If you really want to know the technical details of TLS, have a look at this page: http://an.wikipedia.org/wiki/Secure_Sockets_Layer. For the typical Web Service developer, these details are not really important. However, knowledge of how the first three steps work can help you prevent a lot of problems.
Especially step 3 is of great importance. The client has received a certificate from the server, and has to decide whether it is safe. This decision is based on a few factors.
First of all, the certificate has to have been issued for the domain that has been requested. So if you access a service on http://somecompany.com/service and get a certificate issued for someothercompany.org, the client will reject the certificate. Some clients, such as web browsers allow the users to override this decision and accept the certificate anyway. A web service client doesn’t typically have a user, so there is no room for second chances.
Secondly, the certificates timestamp has to be valid, meaning that it hasn’t reached it’s expiry date yet. Depending of the type of certificate, it is valid from 1 to tens of years.
The third requirement can sometimes give some problems: the client has to trust the certificate. This can best be explained using a real life example. Imagine yourself at the border control on a foreign airport. If you show them a paper with your name and a signature on it, chances are small that they let you through? Why? Because they can’t trust a self-signed certificate, or one that is signed by a relative. However, if that same name is written on a legal passport, given and signed by your country’s authority, border control will trust it, because they trust them. In TLS, it is exactly the same.
If you order a certificate from a certificate authority (CA), nobody will actually know that you have that certificate. And you don’t trust what you don’t know. However, you have paid the CA to sign your certificate. And maybe the CA certificate has been signed with yet another certificate. Now, if you trust the CA, you will automatically trust all certificates that have been signed with that CA. Back to our border control. If you trust the US government to issue correct passports to people, you will automatically trust all passports of US citizens, even if you don’t know that person.
To mark a certificate as trusted, the certificate has to be stored in a so-called “trust store”. Your browser has a truststore that includes the large CA certificates by default. Just look around in the configuration of your browser. You’ll be able to install other certificates if you like. For example, one that you have created and signed yourself.
You can also configure a truststore for your web service client. By default, your JVM will probably include the large CA certificates, such as Verisign and Thawte. If you’re running on an application server, chances are big there is a trust store configured in them, too. Of course, you can override the truststore by defining your own.
Ok, now that we’ve seen a lot of misery on the client side, let’s have a look at what has to happen on the server side. Well, luckily, not all that much. All you have to do is configure your web server to use SSL. Somewhere along the line it will require you configure a certificate to use. And since you probably want to be trusted, make sure to have your certificate signed by a large CA.
The good part is that all communication between client and server is encrypted in such a way, that only these parties are able to read the messages. And, as a bonus, the client is ensured that it is really talking to the server it was expecting to communicate with.
TLS is nice, but if you have a message that will pass a few endpoints, or has to be logged in the mean time, it doesn’t really help you. If you have to keep your data secure after is has arrived at your first endpoint, message encryption could be your solution.
Let’s start off with an example. Let’s image we have a service where consumers can place orders. Just for the sake of the example, the request will first be processed by an endpoint that checks the stocks. If the stocks are sufficient, the payment is processed. If TLS were used between the consumer and the first endpoint, the message would be sent unencrypted. Of course it is possible to encrypt that communication too, but that would probably be a performance hit.
The idea behind encryption is not really complex. The entire message, or part of it is encrypted using the public key part of the certificate. Since the private key is required to decrypt it, only the recipient (or at least only systems with access to the private key) will be able to so. Even if a message is stored for future reference, the contents will be unreadable to any third party.
Typically, only parts of messages are encrypted. You could think of elements containing payment information or other private contents, such as social security numbers. The example project in go ogle code shows an example of a message where an ID is encrypted. Not a really powerful use case, but it shows how the technology works.
As with TLS, message encryption will deal with items 1 and 4. However, it will only do so for the parts of the message that have been encrypted.
Both TLS and message encryption give the communication between consumer and provider some form or privacy and protection against eavesdropping. If configured correctly, they can work transparently to the implementation of both the client and the consumer, but will claim some of your performance.
My next and last article in this series will discuss message signing, which will deal with the security item that hasn’t been covered yet: “Both parties want to be sure that the message is received unchanged”.