October 18, 2021 | By devevon

Modern cryptography is one of the most important aspect of computer and communications security. It is based on mainly mathematics concepts like number theory, computational-complexity theory and probability.

Unlike classical cryptography which manipulates traditional characters, modern cryptography operates on binary bit-string. It could also be proven, under given assumption, to be computationally secure.

**The primary goals that modern cryptography is trying to achieve are:**

- Confidentiality:
- Also known as privacy or secrecy. It means that even if an adversary manages to eavesdrop on one’s message, it could not know the meaning of the message.

- Integrity:
- Confirms that data transmitted is not modified by an unauthorized entity. All modified data should be detected.

- Authentication:
- Provides the identification of the parties that one is communicating with.
- i.e. A cannot pretend to be B when talking or sending data to C.

**There are 2 main types of cryptographic methods that are adopted today:**

- Symmetric (Private Key)
- Asymmetric (Public Key)

**Some key terms to know:**

- Plaintext: message that needs to be encrypted.
- Ciphertext: encrypted plaintext. If encryption is done properly, it reveals no information about the plaintext.
- Key: a randomly generated string used in encryption and decryption

**All cryptography algorithms can be broken down into 3 parts:**

- Key generation, KG () (takes in no parameter): a function outputs a randomly chosen key.
- Encryption, or Enc(Msg, Key): this function takes in a key and a plaintext message, encrypts the plaintext based on the key, and outputs the resultant ciphertext, C
- Decryption, or Dec(C, Key): this function takes in a key and a ciphertext, decrypts the ciphertext based on the key, and outputs the resultant plaintext, M

**For any algorithm to work as intended, if the key is correct, the following must hold:**

i.e. I must get back to the same message if my key(s) is(are) correct.

Symmetric encryption is a type of encryption where only one shared secret key is used to both encrypt and decrypt data (bit-string).

*Topic Description/Background Info*

One Time Pad works by taking a key that is as long as the text you want to encrypt and then performing the XOR operation to get the encrypted text. The same key used to encrypt the text is also used in decrypting, by performing the XOR operation with the encrypted text and the key.

Xor property:

For one time pad, the 3 parts:

- KG(): it will output a randomly generated bit-string that has the same length as the plaintext
- Enc(M, K):
- Message M and Key K must have the same length.
- It will output a ciphertext C, where

- Dec(C, K):
- Ciphertext C and Key K must have the same length
- It will output a plaintext M, where

To summarize and XORing is a cheap operation so it is easy to encrypt and decrypt messages which is an advantage of the One Time Pad.

Note: OTP is proven mathematically to satisfy perfect secrecy

To understand the following extra readings, some understanding in statistics is needed

- Perfect secrecy: https://www.cs.miami.edu/home/burt/learning/Csc609.011/Perfect/#:~:text=A%20cryptosystem%20has%20perfect%20secrecy,one%20key%20that%20connects%20them.
- Proof that OTP satisfies perfect secrecy: http://math.umd.edu/~lcw/OneTimePad.pdf

*OTP Challenge 1: Proper Encryption and Decryption (Stage 1 and Stage 2)*

*Background Info*

The main disadvantage of this encryption algorithm is that it requires a key of the same length as the message to be encrypted. Every time when a message is sent, a key of the same length must be shared as well. (Why not reuse the same key?).

Suppose we have a message of length 2048, we need to send securely a key of length 2048 together with the encrypted message.

In other word, if we are sending a file of size 1GB, in total, we will need to send 2GB worth of load.

*OTP Challenge 2: Attack OTP when the same key is used.*

*Background Info:*

Block Cipher is another symmetric encryption algorithm, it works by take a block of the plaintext and then using a key to pick a permutation of the possible outputs.

For example, for a 3-bits block and 2-bits key

Plaintext | Cipher (Key = 00) | Cipher (Key = 01) | Cipher (Key = 10) | Cipher (Key = 11) |

000 | 100 | 110 | 010 | 010 |

001 | 011 | 001 | 011 | 100 |

010 | 111 | 000 | 101 | 110 |

011 | 101 | 101 | 000 | 011 |

100 | 000 | 010 | 100 | 101 |

101 | 010 | 100 | 111 | 001 |

110 | 110 | 111 | 001 | 000 |

111 | 001 | 011 | 110 | 111 |

Suppose our key = 01, message = 101, then the ciphertext = 100.

Note: not all possible permutations are used here.

For a block that has N-bit inputs there are 2^N! possible permutations and for a key that has k-bits there are 2^k possible keys. Each key will map to a unique permutation. It is very likely that not every permutation will be used.

One of the nice things about Block Cipher is that it is extremely hard to break that is it is very expensive to try since there is no known efficient algorithm that can break Block Cipher without having to brute-force it.

In real life where key size is as long as 256 bits, there will not be a key-plaintext-ciphertext table. Instead, an interesting pseudo-random permutation algorithm will be used to make the encryption algorithm efficient.

e.g.

DES: https://www.geeksforgeeks.org/data-encryption-standard-des-set-1/

*Block Cipher Challenge 1: Based on a key table, encrypt and decrypt*

*Background Info:*

Currently there is not a known efficient way to break a block cipher other than trying out all possible keys.

*Block Cipher Challenge 2: breaking using brute force*

*Background Info*

As computer powers becoming stronger, DES that uses 56-bit key could be broken within a few hours.

A possible way to make it harder to break, apart from using a longer key or changing to AES, is using 3 DES.

3 DES (needs 2 56-bits keys)

- To encrypt:
- 1
^{st}Encrypt with DES the plaintext using Key1 to get C1. - 2
^{nd}Decrypt C1 with Key2 to get C2. - 3
^{rd}Encrypt C2 with Key1 to get the final ciphertext.

- 1
- To decrypt:
- 1
^{st}Decrypt the ciphertext with Key1 to get C2. - 2
^{nd}Encrypt C2 with Key2 to get C1. - 3
^{rd}Decrypt C1 with Key1 to get the plaintext.

- 1

2 DES (?)

Proposed encryption algorithm:

- 1
^{st}Encrypt the plaintext with Key1 to get C1. - 2
^{nd}Encrypt C1 with Key2 to get the final ciphertext.

*Challenge: Attacking 2DES without knowing the key*

*Background Info*

The Electronic Code Block works by breaking the message into equal size blocks and then performing block cipher on each block with the same key then concatenating the result of each of the block ciphers.

*Electronic Code Book Challenge 1: Encryption and Decryption*

*Background Info*

- ECB is deterministic. i.e. On a given input, it will always have the same output.
- It leaves plaintext data patterns in the ciphertext and creates opportunities for frequency analysis.
- Typical example is encrypting images using ECB:
- https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)
- Since the algorithm is deterministic, it is extremely easy to forge messages.

*Electronic Code Book Challenge 2: Attacking the algorithm*

*Background Info*

Unlike ECB, counter mode adds in randomness to the ciphertext.

Given key K and message M,

- Like ECB, counter mode will first divide a long plaintext into multiple N-bits long blocks.
- Randomly generate a N-bits Initialization Vector (IV). Save it as C[0], i.e. the first block of the ciphertext.
- For the i-th plaintext block:
- Encrypt (treat IV as an integer, then add to it. If the result overflows, disregard the most significant bit) using block cipher with key K.
- Using the result from step a., xor with the i-th plaintext block.
- Save the result from step b as or block of the ciphertext.

Or visually,

Src: https://courses.cs.washington.edu/courses/cse484/21sp/slides/cse484-lecture10-sp21.pdf

Given key K and ciphertext C,

- Divide the long ciphertext into multiple N-bits long blocks.
- Take C[0] and treat it as the IV
- To get the i-th plaintext block:
- Pass to the block cipher with key K
- Using the result from step a, xor with the ciphertext block to get the plaintext block

Advantage:

We do not need to inverse the block cipher.

*Counter Mode Encryption Challenge 1: Encrypting a long message using CTR mode encryption*

*Background Info*

There are a few things that we need to know before talking about reusing IV:

- Block Cipher is deterministic. i.e. On a given key and message, a block cipher will always output the same ciphertext. No matter when it is done.
- If messages are not the same, outputs will be random. i.e., you cannot predict the ciphertext of M, given the ciphertext of M’.
- In counter mode, inputs to the block cipher are always different. Based on point 2, we could say the outputs of the block cipher are random. Since we are xoring each message block with a randomly generated bit-string, we are just applying OTP on each block.

What would happen if we reused an IV? Here assume we do not change the key

- IV used to encrypt 2 messages will be the same.
- IV + 1, IV + 2, …, IV + n used in these 2 encryptions will be the same.
- Outputs of the block cipher, (inter 1, inter 2, …, inter N) will be the same since block cipher is deterministic given fixed message and key.
- If inter 1, inter 2, …, inter N are the same in these 2 encryptions, we are essentially applying OTP using a used key which is problematic.

*CTR Mode Challenge 2: attacking a flawed CTR mode encryption algorithm*

*Background Info*

https://courses.cs.washington.edu/courses/cse484/21sp/slides/cse484-lecture10-sp21.pdf

To Encrypt

- A random IV which has the same length as a block will be generated
- Save the IV as C[0] (first block of the ciphertext)
- Let SK = IV, for i = 0, i < number of blocks, i++:
- Xor SK with the Plaintext[i] to get Temp
- Pass Temp through a block cipher with the key K to get C[i + 1]
- Let SK = C[i + 1]

https://courses.cs.washington.edu/courses/cse484/21sp/slides/cse484-lecture10-sp21.pdf

To Decrypt:

- For i = number of blocks – 1, i >= 1, i–:
- Decrypt C[i] using the decryption algorithm of the block cipher with the key K to get Temp
- Xor Temp with C[i – 1] to get Plaintext[i – 1]

*Background Info*

Since we need to pass Temp through a block cipher using the same key, K, all the Temps must have the same length. This means that length of the plaintext must be a multiple of N, where N is the length of a block.

What we are passing to the block cipher in CTR is the randomly generated IV + i. It is guaranteed to have the same length as the initial IV. If the last block of the plaintext has a length < N, we can simply remove the first/last few bits of InterI to make them to have the same length.

Qn: How can we distinguish the padded 0 from the actual value 0?

PKCS#5 and PKCS#7:

Instead of using 0, we pad each byte with the value of total number of bytes added.

e.g.

If we only need to pad 1 byte, we will pad 01 at the end

2 byte: 02 02

3 byte: 03 03 03

Suppose the message is

… | AB 12 19 9C 11 05 F3 D4 | 5E 06

Block size = 8 bytes

The last block has a size of only 2 bytes

- We need to pad 6 bytes to the last block, so the value to pad is 06

Therefore, the padded message will be:

… | AB 12 19 9C 11 05 F3 D4 | 5E 06 06 06 06 06 06 06

Note: there are 7 06’s at the end of the last block, the first one is part of the message.

If the original message’s length is a multiple of N, where N is the block size, an extra block filled with N with be added to the end of the message

e.g. For message like

… | AB 12 19 9C 11 05 F3 D4 | 5E 06 12 51 0E AF BB 9D

Which has all blocks filled. The padded message will be

… | AB 12 19 9C 11 05 F3 D4 | 5E 06 12 51 0E AF BB 9D|08 08 08 08 08 08 08 08

This is to make the last block to always be a padded block. Why is this needed?

We will then encrypt this padded message using CBC.

*Challenge: Determine if a padding is valid*

*Background Info*

There are a few things to keep in mind before going deeper into the topic:

- The last block is always padded
- To get the plaintext[i – 1], we are xoring cipher[i – 1] and Dec(K, cipher[i])
- The decryption algorithm will throw an invalid padding error when the plaintext[i – 1] it decrypted does not have a valid padding.

Without other protection, padding could possibly leak the entire message’s content.

Notation wise:

- Let the last ciphertext block to be C
- Let the second last ciphertext block to be C’
- Let C[i] denotes the i’th byte of the block C, starting from 0
- Let size of each block to be N

Let’s see how we can get the last byte:

- There are 2 ways that a ciphertext can be decrypted without throwing an invalid padding error
- Decrypt the ciphertext without modifying it
- Set the last byte to be 01

- We want to make use of the property 1.b.
- Recall the last step to decrypt a block is xoring with the previous ciphertext block
- We have edit access to the ciphertext block

- Aim: Edit C’[N-1] such that
- We know that, without any modification , where A is the original value
- What if we make to be the last block.
- Based of the xor property, it will output 01 which will not throw an invalid padding error

- Now, we only need to find A.
- We know that there are 2 values that will not make the decryption algorithm to throw an invalid padding error
- 01, i.e.
- A, i.e.

- We just need to xor C’[N-1] with all possible values [02, FF] and send to the decryption algorithm to find the only value that does not throw an invalid padding error. The value will be A. (We only need 256 trials per byte)

- We know that there are 2 values that will not make the decryption algorithm to throw an invalid padding error

How can we extend this to get all other bits?

Note: we already found out the last byte. We need to find the second last byte. What are the values that the last 2 bytes can take such that they will not cause an invalid padding error?

*Challenge: Padding Oracle Attack to find out the entire block*

*Bonus Challenge: Padding Oracle Attack to find out the entire message*

## Leave a Reply