What is TLS? Transport Layer Security Encryption Explained in Plain English

In today‘s digital world, much of our private communication takes place over the public internet. Whether you‘re logging into your bank account, submitting your taxes online, or instant messaging with friends, you want to be sure that your sensitive information is kept confidential and can‘t be intercepted or tampered with by unauthorized parties. That‘s where TLS comes in.

TLS, which stands for Transport Layer Security, is a cryptographic protocol that provides end-to-end security for data sent between applications over the internet. It allows client and server applications to communicate in a way that is private, authenticated and reliable.

At a high level, TLS accomplishes three key things:

  1. Encryption – scrambling the data so that only authorized parties can understand it
  2. Authentication – verifying the identities of the communicating parties
  3. Integrity – ensuring the data cannot be modified or corrupted during transmission

TLS is the successor to the older SSL (Secure Sockets Layer) protocols and is an IETF (Internet Engineering Task Force) standard defined in RFC 5246 and RFC 8446. It is widely used for securing web browsing, email, messaging, Voice-over-IP and many other applications.

TLS/SSL Usage Statistics
Source: SSL.com

As of June 2020, over 91% of page loads in Google Chrome use HTTPS (which is based on TLS), according to Google Transparency Report. Let‘s take a closer look at how TLS works its magic through a process called the TLS handshake.

The TLS Handshake

Before two parties can begin communicating securely with TLS, they need to establish some ground rules and shared secrets. This process is called the TLS handshake and it involves a series of back-and-forth messages between the client and server.

It begins with the client (for example, your web browser) sending a ClientHello message to the server. This message includes which versions of the TLS protocol the client supports, as well as a list of suggested cipher suites.

A cipher suite is a collection of cryptographic algorithms that will be used for the secure connection, including those for key exchange, authentication, encryption, and message integrity checking. Some common examples are RSA, Diffie-Hellman, AES, and SHA.

Here‘s what a ClientHello looks like in the TLS 1.2 protocol:

struct {
    ProtocolVersion client_version;
    Random random;
    SessionID session_id;
    CipherSuite cipher_suites<2..2^16-2>;
    CompressionMethod compression_methods<1..2^8-1>;
    select (extensions_present) {
        case false:
            struct {};
        case true:
            Extension extensions<0..2^16-1>;
    };
} ClientHello;

The server responds with a ServerHello message, specifying the protocol version and cipher suite it has selected from the client‘s options. The server also sends its digital certificate, which contains its public key and is signed by a trusted Certificate Authority (CA). This allows the client to verify the server‘s identity.

Here‘s the structure of a ServerHello in TLS 1.2:

struct {
    ProtocolVersion server_version;
    Random random;
    SessionID session_id;
    CipherSuite cipher_suite;
    CompressionMethod compression_method;
    select (extensions_present) {
        case false:
            struct {};
        case true:
            Extension extensions<0..2^16-1>;
    };
} ServerHello;

Depending on the selected cipher suite, some additional exchange of cryptographic information may take place to establish a shared secret key. This can involve the server sending additional certificates, the client verifying those certificates, and both parties exchanging random values and performing mathematical operations to generate the same secret key.

TLS Handshake
Source: SSL2BUY

The mathematics behind this key exchange can get quite complex, but let‘s look at the two main cryptographic approaches used: asymmetric and symmetric.

Asymmetric vs Symmetric Cryptography

Asymmetric cryptography, also known as public key cryptography, uses two keys: a public key and a private key. The public key, as its name implies, can be openly shared. Anyone can use it to encrypt a message. However, that encrypted message can only be decrypted by the holder of the matching private key. This provides a secure way to establish identity and share secrets.

Some common asymmetric algorithms used in TLS include:

  • RSA: Named after Rivest, Shamir and Adelman, this is the most widely used public key algorithm. It can be used for key exchange, digital signatures and encryption.
  • Diffie-Hellman: A key exchange protocol that allows two parties to establish a shared secret over an insecure channel. It‘s often used in combination with other algorithms for authentication and encryption.
  • Elliptic Curve Cryptography (ECC): A newer alternative to RSA and Diffie-Hellman based on the algebraic structure of elliptic curves. ECC can provide the same level of security with smaller keys, making it more efficient.

In the TLS handshake, asymmetric cryptography is often used for authentication and key exchange. The server shares its public key in its digital certificate. The client then uses this to encrypt a pre-master secret and send it to the server. Only the server can decrypt this message using its private key, and from there both parties use the pre-master secret to generate the same master secret – a symmetric session key.

Symmetric cryptography, in contrast, uses a single secret key for both encryption and decryption. Once both parties have the session key, they can use faster symmetric encryption algorithms for the bulk of their communication.

Some common symmetric encryption algorithms used in TLS include:

  • AES (Advanced Encryption Standard): A block cipher that can use 128, 192 or 256-bit keys. It‘s widely considered the gold standard for symmetric encryption today.
  • ChaCha20: A stream cipher designed as a faster alternative to AES for mobile and IoT devices. It‘s often paired with the Poly1305 message authentication code.
  • 3DES (Triple Data Encryption Standard): An older block cipher that applies the DES cipher three times. It‘s being phased out due to its relatively small 64-bit block size.

Symmetric keys are also used to generate message authentication codes (MACs) which are used to check the integrity of each message. A MAC algorithm takes the message and the secret key as input and produces a fixed-size code that is sent alongside the message. The receiver can recompute the MAC and compare it to the one received to verify the message hasn‘t been altered.

Finishing the Handshake

After the symmetric session key is established, the client and server exchange Finished messages which are encrypted with the session key. By decrypting these messages successfully, both parties verify that the handshake completed without errors and that they have generated the same session key.

At this point the initial asymmetric encryption is replaced by symmetric encryption using the shared session key. Application data can now be exchanged securely, with each message being encrypted and authenticated using the session key.

The TLS Record Protocol

Once the handshake is complete, the client and server begin exchanging application data using the TLS Record Protocol. The record protocol takes the application data, fragments it into manageable blocks, optionally compresses it, applies a MAC, encrypts it, and transmits it as a TLS record.

Here‘s the basic structure of a TLS record:

struct {
    ContentType type;
    ProtocolVersion version;
    uint16 length;
    opaque fragment[TLSPlaintext.length];
} TLSPlaintext;

struct {
    ContentType type;
    ProtocolVersion version;
    uint16 length;
    opaque fragment[TLSCompressed.length];
} TLSCompressed;

struct {
    ContentType type;
    ProtocolVersion version;
    uint16 length;
    select (SecurityParameters.cipher_type) {
        case stream: GenericStreamCipher;
        case block:  GenericBlockCipher;
        case aead:   GenericAEADCipher;
    } fragment;
} TLSCiphertext;

The receiving end reverses this process, decrypting the record with the session key, verifying the MAC, decompressing if needed, and reassembling the application data.

TLS Protocol Versions

It‘s worth noting that TLS has gone through several versions as security standards have evolved. Here‘s a quick rundown:

  • SSL 1.0, 2.0, 3.0: The original Secure Sockets Layer protocols developed by Netscape in the 1990s. All SSL versions have been deprecated due to vulnerabilities.
  • TLS 1.0: Released in 1999 as an upgrade to SSL 3.0. It fixed several security flaws but is now considered deprecated.
  • TLS 1.1: Released in 2006. It added protection against CBC (Cipher Block Chaining) attacks.
  • TLS 1.2: Released in 2008. It added support for newer cipher suites and improved flexibility for negotiation.
  • TLS 1.3: The current standard, finalized in 2018. It made significant improvements to security and performance, removing legacy features and reducing the handshake latency.

Here‘s a chart showing the usage share of different TLS/SSL versions over time, based on data from SSL Labs:

TLS Version Usage Share

As you can see, TLS 1.3 adoption is growing steadily while older versions are being phased out. As a developer, it‘s important to keep your TLS configurations up to date and follow best practices for secure deployment.

TLS Best Practices for Developers

When implementing TLS as a developer, there are several best practices to keep in mind:

  1. Use the latest TLS version: As of 2023, TLS 1.3 should be preferred wherever possible. Fallback to TLS 1.2 only if necessary for compatibility.

  2. Choose strong cipher suites: Prioritize AEAD (Authenticated Encryption with Associated Data) ciphers like AES-GCM and ChaCha20-Poly1305. Avoid legacy ciphers like 3DES and RC4.

  3. Use secure key exchange and authentication: Favor ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) for key exchange and ECDSA (Elliptic Curve Digital Signature Algorithm) for authentication. Use key sizes of at least 2048 bits for RSA and at least 256 bits for ECC.

  4. Ensure proper certificate validation: Verify the server certificate is trusted, unexpired, and matches the domain name. Implement OCSP stapling and CRL checking to ensure certificates have not been revoked.

  5. Enable security headers: Set the Strict-Transport-Security header to enforce HTTPS connections. Use X-Frame-Options, X-Content-Type-Options and Content-Security-Policy headers to protect against common web vulnerabilities.

  6. Keep your dependencies updated: Many TLS vulnerabilities stem from outdated or unpatched libraries. Regularly update your web server, TLS library, and any dependencies to the latest stable versions.

Here‘s an example of configuring TLS securely in Nginx:

ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src ‘self‘; script-src ‘self‘";

And here‘s how you might set up a secure TLS connection in Node.js using the built-in https module:

const https = require(‘https‘);
const fs = require(‘fs‘);

const options = {
  key: fs.readFileSync(‘server.key‘),
  cert: fs.readFileSync(‘server.cert‘),
  minVersion: ‘TLSv1.2‘,
  ciphers: ‘EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH‘,
  honorCipherOrder: true,
  secureOptions: 2,  // Use OpenSSL constants instead: SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end(‘Hello, world!‘);
}).listen(443);

Conclusion

TLS is a crucial component of internet security that works quietly in the background to keep our online communications confidential. Through the TLS handshake process, client and server applications can verify each other‘s identity, establish shared encryption keys, and ensure the integrity of transmitted data.

By combining asymmetric cryptography for authentication and key exchange with symmetric cryptography for efficient secure communication, TLS achieves a balance of security and performance. Its various protocol versions and flexible cipher suites allow it to evolve and remain the go-to standard for encryption in the face of new security threats.

As a developer, understanding how TLS works under the hood can help you make informed decisions about configuring and debugging secure connections. By staying current with the latest TLS best practices and properly implementing them in your applications, you can help ensure your users‘ data remains private and protected.

Similar Posts