I can easily assume that the majority of software engineers are not computer security experts, however; I think there should be no excuse for the average software engineer not to get familiar with basic concepts. For instance, if you were asked: "what is SSL?" I guess it is either you do not know the answer - which is embarrassing - or you think you have an idea. The later is more interesting because the moment you try to answer the question, you may realize that you are not actually confident. To be frank, it is probably the case for various technical terms that we think we are familiar with but in reality the understanding is not concrete. This is simply because terms are repeatedly mentioned but we never get a chance to dig deep about such terms. The end result is fake understanding regardless how difficult or confusing the concept might be. If you do not believe me? start quizzing yourself "What is virtualization?", "What is abstract factory design pattern?", “What is Big-O notation?” etc. Unless you think deeply about a certain topic, your understanding might be insufficient. During my work at two different companies, I was testing software where SSL was a primary feature. It was not a pleasant experience to work on secure software products without enough SSL background. I had to surf the web and read more about it. I found tons of materials that talk about online security. There were indeed few great articles but the majority were misleading because they mixed technical specification with security foundations. In my humble opinion, this is not the best approach to convey understanding, specially for those who have no prior background. Zooming out and looking at layers of abstraction is a better alternative to getting overwhelmed with unnecessary technical details. For that reason, I am not going to talk about securing a web server or how to use OpenSSL. Instead, I am going to explain SSL in plain English. Once basic concepts are clear, working with security related technologies and tools becomes enjoyable and more meaningful. Please also note that the sections below are in order. Each section builds on top of the preceding sections.
Imagine our goal is to send a credit card number between two networked computers without being compromised. Confidential information as it passes from source (ex. Browser) to destination (ex. website) can be intercepted and read by other connected 3d party computers. This is a serious problem and the solution is to scramble the data in such a way it can be read only by source and destination (authorized parties). Converting data (plain text or credit card number in our case) into unreadable form (cipher text) is known as encryption. In the following sections, I will briefly describe the major encryption methods required to better understand SSL.
Cryptographic hashing (ex. MD5, SHA-1) can be viewed as an encryption method in the sense that it transforms input data into an unreadable form. On the other hand, some people may not consider it as an encryption method because there is no way to recover the original text. In either case, hashing is very crucial for computer security, SSL in particular. This technique applies a one way mathematical function on input data of varying length and maps it to a fixed length output called the digest or fingerprint. One way means the function cannot be inverted. For example, if you compute the hash of a text file, there is no (computationally) practical way to recover the file from the hash. Hashing functions are designed to be collision resistant which means no two inputs evaluate to the same digest. In other words, there is no way to change the input data without changing the digest value. All these properties help us insure data integrity. For example, if you download a file from the internet then compute a hash, it should match an expected hash value (usually comes with the file) otherwise the file was tampered with or there was some data loss. Keep this in mind until we talk about digital signature. At that point, things will start to make more sense.
In order to get a sense of what hashing means. Assume we have an input string of characters. A hash function could be as simple as adding the numeric value of each character in the string then taking the total sum as the string digest. Of course, this function suffers from collisions because we can have two different strings yielding the same sum (ex. Anagram strings such as "Listen" and "Silent").
Private Key Encryption
This method is also known as symmetric or secret key cryptography. Symmetric refers to the fact that a single common encryption key is shared between (both) the sender and receiver to encrypt and decrypt the message. Private key encryption is a simple and fast encryption algorithm, however; the drawback is that the two parties must exchange the secret key in a secure way. This sounds ironic, the whole purpose of encryption is to hide the data but now we need to hide the key. To overcome this challenge, we use public key encryption (explained later). There are various secret key based encryption algorithms. Data encryption standard (DES) is one of the most popular ones.
So far, we have learned that a secret key is required to encrypt and decrypt an input message. So how does that happen?. To help you visualize what encryption looks like. Let us assume we have an input string of only 2 characters. Assuming each character is represented by a single byte. One encryption algorithm could be as simple as performing a bit wise XOR operation between each character and a common key of our choice for example number 7 in binary 00001110. To decrypt the message we do another XOR operation between each character in the encrypted text and the secret key 00001110.
Public Key Encryption
Public key encryption is also known as asymmetric key encryption due to the fact that two (mathematically related) keys are involved in contrast to one as in secret key encryption. The sender uses the public key of the recipient to encrypt the message and the recipient uses his or her private (secret) key to decrypt the cipher text. So where is the catch in having two keys? Actually having two keys makes it even less efficient compared to private key encryption. The main advantage is that this algorithm does not require key exchange as in private key encryption. Even if we can exchange a secret key securely, the mere fact of having a single key and sharing it with many parties is a potential security threat. Using a single pair of keys with many parties represents a major breakthrough in cryptography. The secrecy of this method is based on the fact that it is computationally impossible to calculate the private key from the public key.
How does it work?
My intention in this article is to explain SSL using simple terms. Knowing how public key cryptography works is beyond the scope of this post. If you like to get an idea about the mathematical ground of public key encryption you may refer to the following:
- I have a blog post that explains what computationally impossible means. Read that before trying to derive the private key from the public key.
- This article talks about RSA which is one of the most popular public key encryption algorithms. The article is written in an easy to understand style. It explains how the keys are mathematically related and how they are used to encrypt data then decrypt it back.
Digital signature is a direct application of hashing and public key cryptography (explained earlier). It serves two main purposes
- Verify the authenticity of data.
- Insure data integrity.
For example, if someone sends you a document? How do you make sure the document was indeed sent by that person? How do you make sure that the document was not modified by a 3d party? Digital signature provides a solution for these two scenarios. So how does it work? Let us see that.
How does it work?
Assume a sender wants to send a message to a recipient. Here are the steps
- Sender computes a hash of the message
- Sender encrypts the hash using his private key
- Sender attaches the encrypted hash to the message
- Sender sends both the message along with the encrypted hash to the recipient
- Recipient decrypts the hash using the sender's public key
- Recipient computes the hash of the received message
- Recipient compares the computed hash value with the attached hash value.
Aside from technical details, the steps are directly based on the concepts explained earlier in the post. In step 5, If the recipient was able to decrypt the hash then there is no way but the message was indeed sent by the sender. Remember that a pair of public and private keys are mathematically related so there is no way one can decrypt a message unless it was encrypted by a matching public key. This way the recipient verified the authenticity of the message. In step 7, If the hash values do not match then the message was tampered with. Recall that no two messages have the same hash. This way, we have verified the integrity of the message.
Digital certificate in a nutshell is nothing but a file which mainly contains three pieces of information:
- Public key of the entity to secure such as a web server.
- Subject information such as website owner information.
- Certificate digital signature signed by a trusted 3d party called certificate authority.
In other words, digital certificate combines the required information needed to communicate with a given service securely. The public key is used to encrypt data and the digital signature insures that the included public key truly belongs to the certificate owner.
Signing a digital certificate by a certificate authority (CA) falls within a bigger context known as public key infrastructure (PKI) which is beyond the scope of this article. Just keep in mind that CA is a common trusted 3d party that verifies the correctness of information contained in the digital certificate such as public key, owner information and date range during which the certificate is valid. The question is why do we need someone to trust before exchanging public keys to start the encryption process between a sender and a receiver. Well, if there is no common trusted 3d party then any one can create a digital certificate, sign it and claim he or she is Google and read your private emails. You know what ? any one can print a PhD certificate and claims he or she graduated from Stanford but in real life a student goes through a verification process that last few years before given a PhD degree ? It is exactly the same analogy. In summary, certificate authority verifies that the public key included in the digital certificate belongs to the owner or subject name of the certificate.
SSL and TLS
SSL is typically used when a browser connects to a secure website (ex. Online banking). This may not be the case (ex. Developing custom application) however; just keep in mind that SSL and TLS are used to exchange data on the internet securely. SSL (Secure Socket Layer) and TLS (Transport Layer Security) are used interchangeably, however the term SSL is more frequently used. SSL is the old protocol while TLS is its successor. Since we are not discussing design specification, we are not going to worry about the technical differences between the two protocols. Let us now proceed with our discussion. So far, we have learned all basic concepts needed to draw an end to end picture of a typical SSL process. Here is a summary of the steps needed to establish a secure connection between a client and server. Please keep in mind that these steps are only a high level explanation. If you are interested in more details I recommend to search the Internet for the term "SSL Handshake"
- Client ask the server for its digital certificate
- Client decrypts the digital signature of the server certificate using the public key of the certificate authority that singed the certificate
- Client computes the hash of the certificate
- Client compares the computed hash with the decrypted hash. If they are the same it means the server digital certificate is legitimate and can be trusted
- Client picks a secret key for data exchange encryption.
- Client encrypts the secret key using the server public key (found in the certificate)
- Client sends the encrypted secret key to the server
- Now both have the same symmetric key and can establish a secure connection
Since private key encryption is more efficient, we use it to do the actual data encryption, however; exchanging the secret key between the client and server is a problem. To solve this problem, we exchange the key using public key encryption.
Self Signed Digital Certificate
Suppose we have an SSL enabled application, is there a need to purchase a digital certificate from a certificate authority for development and testing ? the answer is no, we can just create a self signed digital certificate simply because we trust ourselves. If we browse a secure website with a self signed digital certificate, the browser is going to warn us that it does not recognize the server certificate. In that case, we can just add the self signed certificate to the list of browser trusted certificates. Again, this is a high level explanation, but if you are interested in more details, I suggest to Google the term "OpenSSL Self Signed Certificate".
Man in the Middle Attack
As we indicated earlier, the purpose of encryption is to scramble data so that it cannot be made use of if intercepted by a third party. It does not make sense to try to guess the original text from cipher text. So what is the deal about man in the middle attack ? It is tricking the sender (or receiver) by impersonating the receiver (or sender). Both the sender and receiver continue communicating with each other without realizing that someone is modifying the data for his good (ex. debugging and testing) or bad (ex. stealing information) advantage. Man in the middle attacker presents his own digital certificate so that he can decrypt the data using his private key. Let us summarize the steps to get a better understanding
- Client tries to connect to a secure server
- Client request gets intercepted by man in the middle
- Man in the middle presents his own digital certificate
- Client accepts the certificate (In real life do not trust any certificate presented to you)
- Client encrypts the data using the attacker’s public key thinking he is using the server's public key
- Man in the middle should be able to decrypt the data using his private key
- Man in the middle retransmits the data to the server
- Of course, this trick can be applied in both directions (ex. from server back to client)
If you are interested to learn how to use man in the middle attack trick to debug an SSL application please refer to the following article.
In this post, I tried to clear out possible confusions around the basics of SSL. I intentionally avoided talking about technical details because 1) In my opinion I think mixing technical details with security foundations adds to the confusion 2) I am not a security architect to share any deep knowledge in that regard however I tried to provide some pointers for those who seek more. Anyway, I hope you enjoyed and benefited from this post.
If you have any questions, comments or feedback please use the comments section below.