Starting from:

$115

CS6035 Assignment 6- Cryptography Solution

CS 6035

Projects / Cryptography
Cryptography
Goals of the Project For Students
• Will get an introduction to both symmetric and asymmetric cryptographic systems
• Will gain an understanding of how these systems are implemented through examples
• Will exploit systems that have certain vulnerabilities
• Will have the opportunity to engage in discussion about advanced topics in cryptography
Information
There is no required VM for this project. All that is required is a Python development environment. Make certain that you are using Python 3. To check your version of Python, open a command prompt and run the command:
The Final Deliverables
You will complete the provided Python file project_cryptography.py and submit it to the autograder in Gradescope.
Open Discussions
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/ 1/2 3/23/25, 7:50 AM Cryptography | CS 6035
For each task we have provided prompts for further discussions. There will be threads created in Ed where students can discuss these topics. Participation is optional and will not be graded.
Good luck!
TABLE OF CONTENTS
• Introduction
• FAQ
• Task 1: Vigenere Ciphers
• Task 2: RSA Warmup
• Task 3: Factor 64-bit Key
• Task 4: Weak Key Attack
• Task 5: Broadcast Attack
• Task 6: Parity Attack
• Task 7: Padding Attack
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/ 2/2

CS 6035

Projects / Cryptography / Task 1: Vigenere Ciphers
Task 1 - Vigenere Ciphers (35 points)
Going letter-by-letter in this manner we build our cipher until we get ZIQYZMC.

Vigenere Square [source: Wikipedia]
Armed with this information, the first two parts of this task will ask you to write the necessary code to handle the encryption and decryption functionality for a Vigenere cipher system.
For the third and final part, you will attempt to crack a Vigenere cipher using a dictionary attack. Ordinary words can make convenient keys because they are easy to remember, but this practice is far from secure. For this task, you are given a cipher and a list of some of the most common words in the English language. One of those words was used as the key to encrypt the cipher, and your job is to write the code to figure out which one it is. For simplicity, you can assume that all words in the original message are also chosen from the provided list of dictionary words.
def vigenere_decrypt_cipher(c: str, keyword: str) -> str: # TODO: Write the necessary code to get the message (m) from the cipher © # using the keyword m = '' return m
def vigenere_encrypt_message(m: str, keyword: str) -> str:
# TODO: Write the necessary code to create a Vigenere cipher (c) of the
# message (m) using the provided keyword c = '' return c
def vigenere_dictionary_attack(c: str) -> str: # TODO: Write the necessary code to get the message (m) from the cipher (c) m = '' return m
Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.
Open Discussion
The Vigenere cipher improves upon the ancient Caesar cipher. Mathematically speaking, how much more complexity does it add and how does it accomplish this? What are some ways that one could add more complexity/security to the Vigenere cipher system?

Task 2: RSA Warmup | CS 6035
Task 2: RSA Warmup
Task 2 - RSA Warmup (10 points)
Now that we’ve reviewed a symmetric key cryptographic algorithm, we can move on to the world of asymmetric key cryptography. RSA is perhaps the best known example of asymmetric cryptography.
In RSA, the public key is a pair of integers (N, e), and the private key is an integer d.
To encrypt integer m with public key (N, e), we use the formula:

To decrypt cipher integer c with private key d, we use the formula

In this task you will write the code to perform the encryption and decryption steps for the RSA cryptographic algorithm. Finally, you will write the code necessary to calculate the private key d when given the factors of the public key N (i.e. p and q).
def rsa_decrypt_cipher(n: int, d: int, c: int) -> int: # TODO: Write the necessary code to get the message (m) from the cipher (c) m = 0 return m
def rsa_encrypt_message(m: int, e: int, n: int) -> int: # TODO: Write the necessary code to get the cipher (c) from the message (m) c = 0 return c
def rsa_calculate_private_key(e: int, p: int, q: int) -> int: # TODO: Write the necessary code to get the private key d from # the public exponent e and the factors p and q d = 0 return d
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_warmup.html
Task 2: RSA Warmup | CS 6035
Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.
Open Discussion
Did you try to decrypt a cipher by using a line of Python code something like this: m = c ** d % n?
Did it work? (Hint: It did not.) Why not? After all, the math is correct.
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_warmup.html
Task 3: Factor 64-bit Key | CS 6035
Task 3: Factor 64-bit Key
Task 3 - RSA Factor A 64-Bit Key (10 points)
Modern day RSA keys are sufficiently large that it is impossible for attackers to traverse the entire key space with limited resources. But in this task, you’re given a unique set of RSA public keys with a relatively small key size (64 bits).
Your goal is to get the factors (p and q) of each key. You can use whatever methodology you want. Your only deliverable is a formatted json file containing p and q. To get your unique set of keys, you must update the task.py file located in the task folder with your 9-digit GT ID, and then run it. Find the section below in the provided task_factor_64_bit_key.py file:
STUDENT_ID = '123456789'
##############################################
def rsa_factor_64_bit_key() -> typing.Dict[str, typing.Dict[str, int]]:
return { 'test_1': {
'p': 0,
'q': 1
},
'test_2': {
'p': 0,
'q': 1
},
'test_3': {
'p': 0,
'q': 1
},
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_factor_64_bit_key.html

Task 3: Factor 64-bit Key | CS 6035
'test_4': {
'p': 0,
'q': 1
},
'test_5': {
'p': 0,
'q': 1
}
}
Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.
Open Discussion
If 64-bit keys aren’t safe, then what size is appropriate? Is there a trade-off between size and performance?
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_factor_64_bit_key.html
Task 4: Weak Key Attack | CS 6035
Task 4: Weak Key Attack
Task 4 - RSA Weak Key Attack (15 Points)
Read the paper “Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network Devices”, which can be found at: https://factorable.net/weakkeys12.extended.pdf. The essay is essential to understanding this task. Do not skip it, do not skim it, read the whole of it.
You are given a unique RSA public key, but the RNG (random number generator) used in the key generation suffers from a vulnerability described in the paper above. In addition, you are given a list of public keys that were generated by the same RNG on the same system. Your goal is to write the code to get the unique private key (d) from your given public key (N, e) using only this provided information.
def rsa_weak_key_attack(given_public_key_N: int, given_public_key_e: int, public_key_list: typing.List[int # TODO: Write the necessary code to retrieve the private key d from the given public # key (N, e) using only the list of public keys generated using the same flawed RNG d = 0 return d

Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.
Open Discussion
Have you ever heard the saying, “Never roll your own crypto?” What are some ways (besides this particular attack - we don’t want you to give too much away) that doing so can cause unintended problems? Can you point to any specific examples or known exploits?
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_weak_key_attack.html
Task 4: Weak Key Attack | CS 6035
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_weak_key_attack.html Task 5: Broadcast Attack | CS 6035
Task 5: Broadcast Attack
Task 5 - RSA Broadcast Attack (15 Points)
A message was encrypted with three different 1,024-bit RSA public keys N_1, N_2, and N_3, resulting in three different ciphers c_1, c_2, and c_3. All of them have the same public exponent e = 3.
You are given the three pairs of public keys and associated ciphers. Your job is to write the code to recover the original message.
def rsa_broadcast_attack(N_1: int, c_1: int, N_2: int, c_2: int, N_3: int, c_3: int) -> int: # TODO: Write the necessary code to retrieve the decrypted message
# (m) using three different ciphers (c_1, c_2, and c_3) created # using three different public key N's (N_1, N_2, and N_3)
m = 0
return m
Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.
Open Discussion
In addition to the low public exponent being used, this attack is possible because a textbook implementation of RSA is being used. In the real world, there are common mitigating tactics used.
What are some examples? Why else are they important?
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_broadcast_attack.html
Task 5: Broadcast Attack | CS 6035
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_broadcast_attack.html Task 6: Parity Attack | CS 6035
Task 6: Parity Attack
Task 6 - RSA Parity Oracle Attack (15 Points)
By now you have seen that RSA treats messages and ciphers as ordinary integers. This means that you can perform arbitrary math with them. And in certain situations a resourceful hacker can use this to his or her advantage. This task demonstrates one of those situations.
Along with an encrypted message (c), you are given a special function that you can call - a parity oracle. This function will accept any integer value that you send to it and decrypt it with the private key corresponding to the public key that was used to encrypt the given cipher (c). The return value of the function will indicate whether this decrypted value is even (true) or odd (false). Armed with this function and a little modular arithmetic, it is possible to crack the encrypted message. Your goal is to write the code necessary to decrypt the original message (m) from the given cipher (c).
def rsa_parity_oracle_attack(c: int, N: int, e: int, oracle: Callable[[int], bool]) -> str: # TODO: Write the necessary code to get the plaintext message
# from the cipher (c) using the public key (N, e) and an oracle # function - oracle(chosen_c) that will give you the parity
# of the decrypted value of a chosen cipher #(chosen_c) value using the hidden private key (d)
m = 42
# Transform the integer value of the message into a human readable form message = bytes.fromhex(hex(int(m_int)).rstrip('L')[2:]).decode('utf-8')
return message
Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_parity_oracle_attack.html
Task 6: Parity Attack | CS 6035
Open Discussion
https://github.gatech.edu/pages/cs6035-tools/cs6035-tools.github.io/Projects/RSA_Cryptography/RSA_parity_oracle_attack.html

Task 7: Padding Attack
Task 7: Task CBC Padding Oracle
The Advanced Encryption Standard (AES) is a set of standards for encryption set by the U.S. National Institute of Standards and Technology. One of these standards is the Cipher Block Chaining (CBC).
CBC uses a fixed length set of bits known as a block, a unique binary sequence known as an Initialization Vector (IV), and a key. The encryption is accomplished in the following sequence.
1 Add padding to the plaintext until the appropriate block length.
2 XOR the block with the IV.
3 Encrypt the new block with the key.
The chaining part comes into play when encrypting multiple blocks. When working on the next block you follow similar steps with one main difference.
1 Add padding to the plaintext until the appropriate block length.
2 XOR the block with the previous cipher text.
3 Encrypt the new block with the key.
The formula is as follows:

Decryption works in reverse.
1 Decrypt the cipher text with the key.
2 XOR the block with the IV
3 Repeat for latter blocks using the previous plain text as the new IV.
The formula is as follows:

For this task we will be working with an attack known as the padding oracle attack. The padding oracle works under the idea that the server is leaking information about the padding. With this information it is possible to both decrypt and encrypt messages.
For this one section of the assignment you will be asked to use a library outside of the standard. In this task you will use the pycryptodome library. This can be manually downloaded from this link https://github.com/Legrandin/pycryptodome. Alternatively it can be downloaded through pip with the following command: pip install pycryptodome
This task will be the only outside library used.
The first 2 steps of this extra credit will be using a simplified version of padding. In a real world application blocks will be in bits and will typically use or something similar depending on what standard is being used.
def cbc_encrypt_128(key: bytes, IV: bytes, m: str) -> str: # TODO: Write the necessary code to encrypt the message
# (m) using the provided key and IV # the necessary block length is 128 bits
# pad with the byte '' # Do Not modify code above this line # Code Below Here c = 0 return b64encode(c).decode("utf-8")
def cbc_decrypt_128(key: bytes, IV: bytes, c: bytes) -> str: # TODO: Write the necessary code to decrypt the cipher
# (c) using the provided key and IV
# Do Not modify code above this line # Code Below Here m = 0 return m
Step 3 of this task is to write one of the core functions of an oracle which will test if the padding follows pkcs guidelines. This check is often the information that the oracle can leak. For this task you must assume that there will always be at least 1 byte of padding, but there does not always have to be a message attached.
def check_padding(padding) -> bool: # TODO: Write the necessary code to check # if the padding matches PKCS standards is_pkcs_padded = "This variable should be a bool value"
return is_pkcs_padded
These steps can all be tested using the test_task_cbc_ python files. You can do so with the following commands:
python test_task_cbc_decrypt.py python test_task_cbc_encrypt.py python test_task_cbc_pkcs.py
Resources
https://en.wikipedia.org/wiki/Padding_oracle_attack https://www.pycryptodome.org/
Submission Details
You will write your code in the specified function stub(s) found in the provided project_cryptography.py file. When ready, submit this file to the Project Cryptography autograder in Gradescope.

More products