Introduction

Welcome to the first lesson of our course, "Foundations of Encryption for TLS". In this lesson, we will explore the fascinating world of encryption, starting with the basics and gradually moving towards more advanced techniques. Encryption is a crucial aspect of securing data, ensuring that sensitive information remains confidential and protected from unauthorized access. By the end of this lesson, you will have a solid understanding of different encryption methods and how they are applied in real-world scenarios.

The Basics of Encryption

Let's begin with the fundamentals of encryption. Encryption is the process of converting plain text into a coded format, known as ciphertext, to prevent unauthorized access. One of the simplest and oldest encryption techniques is the Caesar cipher. The Caesar cipher involves shifting the letters of the alphabet by a fixed number of positions. For example, with a shift of 3, 'A' becomes 'D', 'B' becomes 'E', and so on.

To encrypt a message using the Caesar cipher, each letter in the plaintext is shifted by the specified number of positions. To decrypt, the process is reversed by shifting the letters back by the same number of positions. Here's a quick example in TypeScript:

This simple example demonstrates how a message can be encrypted and decrypted using a shift key. Depending on the implementation, it is generally preferred to use the modulo operator, similar to the Vigenère table, to handle wrap-around in the alphabet. However, since all characters in software are assigned sequential numeric values, it is possible to skip this modulo operation for our simplification purposes.

While the Caesar cipher is easy to understand, it is not secure for modern applications. The main weakness of the Caesar cipher lies in its predictability. Since there are only 25 possible shifts (excluding shift 0, which leaves the text unchanged), an attacker can easily brute-force decrypt the message by trying all possible shifts. Additionally, letter frequency analysis can quickly reveal patterns, as common letters in English (e.g., 'E' and 'T') will still appear frequently in the encrypted text. These weaknesses make the Caesar cipher unsuitable for securing sensitive information.

Introducing XOR Encryption

Next, we'll explore XOR encryption. Before diving into the details, let's understand the core concept of this encryption method. XOR encryption is based on a straightforward property: WORD ⊕ KEY ⊕ KEY = WORD. This implies that if two parties share a secret key KEY, they can use it to both encrypt and decrypt messages. It's a reversible operation where applying the same key twice returns you to the original message. This property facilitates secure communication between parties using the shared key.

As a refresher, XOR, also called exclusive or, is the boolean operator with the following truth table:

ABA ⊕ B
000
011
101
110

To perform the most basic XOR encryption, we use a key and the plaintext in bytes, and XOR them together. Let's illustrate this using the string "Hello" and the numeric key 3 (00000011).

We take the first character, which is 72 in ASCII. Bitwise XOR'ing 72 with 3 gives us 01001000 ⊕ 00000011 = 01001011 = 75. This is calculated by adding the values of the bits that are set to 1: 2^6 + 2^3 + 2^1 + 2^0 = 64 + 8 + 2 + 1 = 75.

75 in ASCII is K, giving us our first encrypted character. Performing the same action for the remaining characters gives us the following result:

CharacterASCII ValueXOR with Key (3)Resulting ASCIIResulting Character
'H'7272 ⊕ 3 = 7575'K'
'e'101101 ⊕ 3 = 102102'f'
'l'108108 ⊕ 3 = 111111'o'
'l'108108 ⊕ 3 = 111111'o'
'o'111111 ⊕ 3 = 108108'l'

The encrypted cipher is therefore Kfool.

Say we have two people, Alice and Bob, using this basic XOR encryption to talk to each other. You, as an eavesdropper listening to their conversation, pick up on the following messages:

  1. Kfool#Boj`f"
  2. Kfool#Ala"

Those with a keen eye might be able to pick out the original meaning:

  1. In both of the messages, we can see that Kfool is followed by a #, presumably corresponding to a space character. Additionally, both messages end with a ", which presumably is some kind of punctuation.
  2. We know that l -> o and e -> f, so the first message ends with an e, and the second message ends with a three-letter word containing o.

Following clues like these, we can rather clearly point out that the messages say:

  1. Hello Alice!
  2. Hello Bob!

However, we're not done yet. Those with an even keener eye might have noticed the symmetry in the two messages - for example, that the A from Alice has turned into a B, and vice versa. The ls in Hello have been turned into o, and vice versa. This is not by sheer accident, and is in fact a property of XOR itself. No matter which 2 columns you have, you can get the third simply by XORing. Consequently, it's more correct to say that l <-> o and e <-> f. Feel free to try it out by covering one of the columns in the truth table!

This characteristic is what makes XOR encryption useful in scenarios where both parties have a shared private key, as it allows for simple and efficient encryption and decryption.

However, seeing as we just cracked the code, plainly XORing the key and plaintext is insufficient for secure encryption. We would need to include some more advanced additional encryption methods on top of the XOR to make it safer. To summarize, XOR encryption is more secure than the Caesar cipher but still has its limitations. Here's how it works in TypeScript:

Transitioning to Modern AES Encryption

As we move towards more secure encryption methods, we arrive at AES (Advanced Encryption Standard). AES is widely used in modern applications due to its strength and efficiency. It is too complex to go into today, but here is a short summary of how it works:

  1. Block Cipher Structure: AES encrypts data in fixed-size blocks, unlike XOR, which operates on individual bits. This block structure helps prevent patterns from emerging in the ciphertext.

  2. Multiple Rounds: AES uses multiple rounds of encryption, each involving complex transformations, making it much harder to reverse-engineer compared to the single operation in XOR.

  3. Substitution-Permutation Network: AES employs a combination of substitution and permutation to provide non-linearity and diffusion.

  4. Key Expansion: AES uses a key schedule to generate different round keys from the original key, ensuring that each round of encryption is unique, unlike XOR, which uses a single key throughout.

  5. Standardization and Analysis: AES has undergone extensive cryptanalysis and is standardized by NIST, providing confidence in its security, whereas XOR's simplicity makes it inherently weak against cryptanalysis.

AES in CBC mode requires an Initialization Vector (IV) to ensure that identical plaintext blocks produce different ciphertexts. This prevents pattern recognition, a weakness in simpler encryption schemes. The IV should be randomly generated for each encryption operation and does not need to be secret, but it must never be reused with the same key, as doing so can compromise security.

We'll show an AES-256-CBC encryption implementation with a randomly generated salt and IV:

AES encryption is a cornerstone of secure communications, providing robust protection for sensitive data. It is widely used in various applications, including TLS, to ensure data confidentiality and integrity.

Conclusion

In this lesson, we have covered the basics of encryption, starting with simple techniques like the Caesar cipher and XOR encryption, and progressing to modern methods like AES. Understanding these concepts is essential for anyone interested in securing data and communications. As you move on to the practice section, you'll have the opportunity to implement these encryption techniques and solidify your understanding. Let's get started!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal