So TLS is the backbone of internet encryption protocols today. Whenever you're building a system, there's no point in really looking at options today - we just use TLS. But TLS isn't magic security dust you can sprinkle on things to make them secure. It's a protocol that allows a client and a server to select an encryption algorithm for a session. And if you misconfigure the protocols you'll support, your TLS implementation can end up just a little better than no TLS at all.

So, in a nutshell, TLS uses a key exchange protocol with public/private keys briefly, in the beginning of session configuration, to negotiate a session key that's then used for the remainder of the session. The session key encrypts communication using some kind of symmetric encryption algorithm. The protocol's designed this way because asymmetric encryption (i.e. encryption using public/private key pairs) is computationally expensive. Symmetric encryption is much cheaper, and if you use the right algorithm, at least as strong.

Now, one of the biggest problems with TLS misconfigurations is not being specific with the protocol's servers support. If when you configure your system you select computationally weak algorithms as acceptable, attackers can potentially force a downgrade to those weak algorithms and then break the adopted encryption.

Now, these algorithms are assembled into sets called cipher suites. These suites contain an asymmetric algorithm, a symmetric algorithm, and a MAC algorithm. This reduces the number of algorithm negotiations that need to occur by removing many of the possible combinations.

The handshake looks like this:

This is the client hello. Here, the client requests an encrypted session with the server, submits its list of cipher suites, and indicates the TLS version it can use.

This is the server hello. The server responds with the cipher suite and TLS version to use. It also sends over its certificate and public key.

The client verifies that the certificate creates a pre-master key based on a random value. It sends the key to the server encrypted with the server's public key.

The server uses it's private key to decrypt the pre-master key and uses the pre-master key to create a shared secret key. The client does the same thing - this is important to note. The shared secret key never crosses the wire but is instead created independently on both ends of the channel.

The client sends an encrypted message with the shared key.

The server decrypts the message with the key it generated and returns the message to the client encrypted with the key it derived.

If the client decrypts the message correctly, the client and server begin communicating over the secure channel with the shared secret key.

Note that step one above is in cleartext, and step two is protected by the server's public key. Step three is protected by the generated shared secret key. In either step one or two, weak algorithms can result in keys that can be stolen, and by doing so, compromise the connection.