When we need to pass information along to someone, different things help us verify with whom we’re speaking. Identifiers such as voice, location and appearance help us to recognize someone and feel comfortable sharing information. How do we create this same trust digitally and ensure that information we’re sending from our devices makes it to the intended recipient?
The Standard: SSL
Today, SSL is the standard for creating this virtual trust and establishing secure communication between devices. Unfortunately, it’s also easy to implement SSL in such a way that opens transmitted data up to the very vulnerabilities from which SSL tries to shield it. Let’s talk about best practices for SSL implementation and how to protect data from man-in-the-middle (MITM) attacks.
The idea behind SSL is to protect the communication between the sender and receiver in order to prevent eavesdropping. To achieve this, the parties must be able to validate that the remote party to which they are connected is the intended party. After this validation, the parties create a key that’s used to encrypt all data between them for the session. Because of the predominance of eavesdropping attacks like MITM, it’s important to validate the identity of each party.
The guiding principle of validation is trust in the certificate authority (CA) entities that provide certificates of authenticity to web service owners. There are a set of top-level CAs whose certificates can be trusted. These CAs may not be the ones to actually issue a specific certificate – a CA may authorize another CA to issue it. By following the trail all the way to the trusted root CA, the certificate is verified and as a result we can trust the server.
Both web services and non-web applications use certificate validation to establish trust, but a lot of applications skip validation and end up as easy targets for MITM attacks. The primary reason validation is skipped is that the host does not have a signed certificate from a trusted CA. Given that there are times when it may not be feasible to have a host with a signed certificate, how can we validate the host without one?
If we squint at the design, it's easy to see that the distributed trust offered by the CAs could be replaced by trust established over some other secure channel. For example, many services require that the user create an account before using their service. These service credentials are typically used to authenticate the user but could also be used to validate the service.
An easy way to use this is to allow the SSL handshake to complete without server certificate validation. We can use the certificate to create a fingerprint and package this along with both a random and fixed magic number and then encrypt this package with the user’s password. The encrypted file is sent to the server, which can use the stored password to decrypt the file, validate the magic number and check the fingerprint against its certificate. If the fingerprint matches, the server increments the random number and sends that to the client along with the peer certificate’s fingerprint. If the client receives nothing or incorrect information back from the server, it can halt further communication.
This type of secondary validation can be easily incorporated into most SSL clients. The key is that the client and server are able to verify that each is valid and establish trust. Data can be sent once this trust is established, ensuring that it’s protected as it moves across the network.