Lab 3
Lab 3
1. List of collaborators (on all parts of the project, not just the writeup)
2. List of references used (online material, course nodes, textbooks, wikipedia,...)
3. Number of late days used on this assignment
4. Total number of late days used thus far in the entire semester
If any of this information is missing, at least 20% of the points for the assignment will automatically
be deducted from your assignment. See also discussion on plagiarism and the collaboration policy
on the course syllabus.
While we provide you with the tools to run this lab at any platform (Windows, Linux and Mac OS),
I strongly recommend working at a Linux or Mac OS machine as it will make things considerably
easier for you. The instructions given for the rest of the description of the lab are therefore explicitly
for this case (unless otherwise noted).
Administration: This lab will be administered by Sophia Yakoubov.
Introduction
In this lab, you will investigate vulnerabilities in RSA, when it is used incorrectly.
Objectives:
• Understand how to apply RSA encryption and digital signatures.
• Investigate how using RSA incorrectly can compromise confidentiality and integrity.
1 Getting Familiar with RSA
1.1 Textbook RSA
Here, we summarize a naive version of the RSA (“textbook RSA") encryption and digital signatures
schemes. This version of RSA should not be used; you will show in this lab several ways in which it
can be vulnerable. Consult https://en.wikipedia.org/wiki/RSA_(cryptosystem) for more
detail.
1.1.1 Encryption
Below we describe the key generation (KeyGen), encryption (Enc), and decryption (Dec) algorithms
of RSA.
1. KeyGen:
As an example, say that during KeyGen, I choose p = 5 and q = 11. Therefore, I have n = 55. If
I choose e = 3, I need to find a d such that 3d mod (5 − 1)(11 − 1) = 3d mod 40 = 1. I can try a
few numbers, and see that 3 × 27 mod 40 = 81 mod 40 = 1, so I set d = 27.1
Now, say that you know only n = 55 and e = 3. Encryption is just raising the message m to the
power of e; you can encrypt m = 51 as c = 513 mod 55 = 132651 mod 55 = 46.
Decryption is the inverse of encryption; it takes the e-th root of the ciphertext. e and d are chosen in
such a way that raising to the power of d is the same as taking the eth root. Therefore, I, who also
know d = 27, can decrypt c = 46 by taking m = 4627 mod 55 = 51.
Taking the eth root of a value modulo an n whose factorization you don’t know is considered to be
unrealistic for large numbers. However, in our example, someone else, who doesn’t know d = 27,
can also figure out what m is, just by trying each number modulo 55 and raising it to e = 3. (If they
1 In reality, there are way more efficient ways to do this than just trying a few numbers!
2
get 46, they know they’ve found the right m!) This is only possible because we chose small p and q.
If p and q are over 1000 bits long, instead of just 5 bits long, decryption without knowledge of d (or
the factorization of n) becomes unrealistic.
1.2.1 Encryption
To encrypt a message m using RSA PKCS #1 version 1.5, the message is padded as follows:
00 02 |RR·{z
· · RR} 00 m
|{z}
at least 8 random non-zero bytes the message itself
00 01 |FF·{z
· · FF} 00 3021300906052B0E03021A05000414
| {z } XX · · XX}
| ·{z
k/8 − 38 bytes wide ASN.1 “magic” bytes 20-byte SHA-1 digest
The result is signed using the “textbook RSA" signing function. The algorithms that check the
digital signatures need to be implemented very carefully. In Part 5, you will show that if the
implementation of the verification algorithm is slightly off, PKCS1.5 signatures can be forged.
NOTE: The implementation vulnerabilities that are explored in this lab have occurred often enough
in the wild that many cryptographers and practitioners have concluded that using RSA PKCS
3
v1.5 is not a good idea. RSA-OAEP is the suggested choice for RSA encryption. See https:
//tools.ietf.org/html/rfc3560.)
Avoiding the attacks discussed in this lab has also been cited as motivation for using elliptic curve
cryptographic signatures (e.g., ECDSA) instead of RSA.
Nevertheless, RSA is still widely used in practice.
• text_to_int: takes in a string and returns an integer which can be used in RSA.
• find_root: takes in integers x and r, and returns the integer component of the rth root of
x. (Python’s built in pow function can be used to do this, but it doesn’t work for very large
‘long’-type values.) √
For instance, find_root(x = 50, r = 2) = 7. 50 ∼ 7.07106, and 7 is the integer part of
7.07106.
• combine_moduli: takes in two integer moduli n1 and n2 and two integers x1 and x2 , and
returns an integer x mod n1 n2 such that x mod n1 = x1 and x mod n2 = x2 .
For instance, combine_moduli(n1 = 5, n2 = 7, x1 = 2, x2 = 3) = 17, since 17 mod 5 = 2, and
17 mod 7 = 3.
The following shows how to use Python to do some basic RSA operations:
# save the public and private keys to files and read them back:
open('key.pub', 'w').write(public_key.exportKey())
open('key.priv', 'w').write(key.exportKey())
4
# read the public key in:
recovered_public_key = RSA.importKey(open('key.pub', 'r').read())
assert recovered_public_key == public_key
# read the private key in:
recovered_key = RSA.importKey(open('key.priv', 'r').read())
assert recovered_key == key
We can also use math operations in Python to explore RSA ciphertexts and signatures manually.
For instance, you can manually verify the signature. The modulus can be accessed as public_key.n,
and the public exponent can be accessed as public_key.e.
5
2 Small Message Space Attack
Imagine that you are a government agent trying to determine when your neighboring country,
Malland, will attack. Open part2_ctext to find a “textbook RSA" ciphertext sent by Malland to
its ally, Horridland. You know that the Mallanders are likely to be saying one of three things:
The file part2_key.pub contains Horridland’s public key. Use this knowledge to figure out what
the message is.
What would you do to prevent Malland from executing the same attack on ciphertexts you send?
What to submit
2. A file named part2.txt with your suggestion for how to prevent the attack you executed in
part2.py.
6
Defense: Padding A technique that prevents this attack is padding, which is used in PKCS #1.
Padding artificially increases the size of the message so that it is almost as big as the modulus n by
adding extra characters or bits to the message. Why would padding help prevent this attack?
What to submit
2. A file named part3.txt that explains why padding prevents the attack you executed in
part3.py.
4 Broadcast Attack
Since you thwarted Malland’s plots with Horridland, Malland enlisted the help of two more allies -
Awfuland and Badland. Horridland, Awfuland and and Badland made the mistake of all having the
same low encryption exponent, e = 3. Their public keys are in part4_key1.pub, part4_key2.pub,
and part4_key3.pub, repectively. Malland sends Horridland, Awfuland and Badland a plan of
attack, still using “textbook RSA" encryption. You get your hands on all three ciphertexts:
Use the fact that all three ciphertexts use the same low encryption exponent to figure out what their
plan of attack is.
Hint: Use the provided function combine_moduli in tools.py.
If Malland padded the message by adding enough ‘1’ characters to the end to make it almost as
long as the modulus, would that prevent you from recovering their message? If not, how could
Malland go about thwarting you?
7
What to submit
2. A file named part4.txt that explains whether padding the message with ‘1’ characters
prevents the attack you executed in part4.py, and if not, how that attack could be prevented.
00 01 |FF·{z
· · FF} 00 3021300906052B0E03021A05000414
| {z } XX · · XX}
| ·{z
k/8 − 38 bytes wide ASN.1 “magic” bytes 20-byte SHA-1 digest
When PKCS padding is used, it is important for implementations to verify that every bit of the
padded, signed message is exactly as it should be. It is tempting for an implementor to validate the
signature by first stripping off the 00 01 bytes, then some number of padding FF bytes, then 00, and
then parse the ASN.1 and verify the hash. If the implementation does not check the length of the FF
bytes and that the hash is in the least significant bits of the message, then it the public verification
exponent e is low, is possible for an attacker to forge values that pass this validation check.
Say that e = 3, as in Parts 3 and 4. If the length of the required padding, ASN.1 bytes, and hash
value is significantly less than n1/3 then an attacker can construct a cube root over the integers
whose most significant bits will validate as a correct signature, ignoring the actual key. To construct
a forged signature that will validate against such implementations, an attacker simply needs to
construct an integer whose most significant bytes have the correct format, including the hashed
message, pad the remainder of this value with zeros or other garbage that will be ignored by the
vulnerable implementation, and then take a cube root over the integers, rounding as appropriate.
8
Historical fact: This attack was discovered by Daniel Bleichenbacher, who presented it in a
lightning talk at the rump session at the Crypto 2006 conference. At the time, many important
implementations of RSA signatures were discovered to be vulnerable to this attack, including
OpenSSL. In 2014, the Mozilla library NSS was found to be vulnerable to this type of attack:
https://www.mozilla.org/security/advisories/mfsa2014-73/.
Horridland is still using a broken implementation of signature verification; in fact, below is the code
they are using.
ASN1_MAGIC = "003021300906052b0e03021a05000414"
Open part5_key.pub to find Malland’s public verification key. You want to tell Horridland to re-
treat, and make them believe that it’s a message from their ally Malland. Using the signature forgery
technique described above, produce an RSA signature on “retreat immediately" that Horridland
would accept.
Since 2010, NIST has specified that RSA public exponents must be at least 216 + 1. Briefly explain
why Bleichenbacher’s attack would not work for these keys.
What to submit
9
(b) Prints a valid signature on the message under the given public key.
2. A file named part5.txt containing your answer to the question above (why Bleichenbacher’s
attack wouldn’t work with a high public verification exponent).
1. A file named part6.txt containing the name and version of the network protocol that uses
RSA on the internet, and a citation to your source.
Submission Checklist
• Part 2:
1. part2.py
2. part2.txt
• Part 3:
1. part3.py
2. part3.txt
• Part 4:
1. part4.py
10
2. part4.txt
• Part 5:
1. part5.py
2. part5.txt
• Section 6:
1. part6.txt
11