This shows you the differences between two versions of the page.
|
ic:laboratoare:11 [2019/12/02 07:01] marios.choudary |
ic:laboratoare:11 [2020/11/05 17:53] (current) acosmin.maria |
||
|---|---|---|---|
| Line 55: | Line 55: | ||
| - | |||
| - | <hidden> | ||
| - | The solution is {{:ic:laboratoare:lab_dhe_solved.zip|here}}. | ||
| - | </hidden> | ||
| === Bonus 1 === | === Bonus 1 === | ||
| Line 68: | Line 64: | ||
| Use the secret key to encrypt some data (see previous labs) and check that the other party can decrypt it. | Use the secret key to encrypt some data (see previous labs) and check that the other party can decrypt it. | ||
| - | ==== Exercise 2: Merkle's puzzles (4p) ==== | + | ==== Exercise 2: RSA parity oracle (4p) ==== |
| + | |||
| + | Generate a 1024 bit RSA key pair using the Python's Crypto module. | ||
| + | |||
| + | Write an oracle function that uses the private key to answer the question "is the plaintext of this message even or odd" (is the last bit of the message 0 or 1). Imagine for instance a server that accepted RSA-encrypted messages and checked the parity of their decryption to validate them, and spat out an error if they were of the wrong parity. | ||
| + | |||
| + | Anyways: function returning true or false based on whether the decrypted plaintext was even or odd, and nothing else. | ||
| + | |||
| + | Take the following string and un-Base64 it in your code (without looking at it!) and encrypt it to the public key, creating a ciphertext: | ||
| + | <note> | ||
| + | VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ== | ||
| + | </note> | ||
| + | |||
| + | With your oracle function, you can trivially decrypt the message. | ||
| + | |||
| + | Here's why: | ||
| + | * RSA ciphertexts are just numbers. You can do trivial math on them. You can for instance multiply a ciphertext by the RSA-encryption of another number; the corresponding plaintext will be the product of those two numbers. | ||
| + | * If you double the original plaintext multiply the ciphertext by (2**e)%n). | ||
| + | * If the plaintext after doubling is even, doubling the plaintext didn't wrap the modulus --- the modulus is a prime number. | ||
| + | |||
| + | That means the plaintext is less than half the modulus. | ||
| + | |||
| + | You can repeatedly apply this heuristic, once per bit of the message, checking your oracle function each time. | ||
| + | |||
| + | Your decryption function starts with bounds for the plaintext of [0,n]. | ||
| + | |||
| + | Each iteration of the decryption cuts the bounds in half; either the upper bound is reduced by half, or the lower bound is. | ||
| + | |||
| + | After log2(n) iterations, you have the decryption of the message. | ||
| + | |||
| + | Decrypt the string (after encrypting it to a hidden private key) above. | ||
| + | |||
| + | {{:ic:laboratoare:parity_oracle.zip}} | ||
| + | |||
| + | ==== Exercise 3: Merkle's puzzles (4p) ==== | ||
| Alice wants to share a secret with Bob, but she knows that if she explicitly tells it to Bob, Eve somehow will find out (she hears everything). So she and Bob establish a small game which helps them think about the same secret, without saying it. The game goes like this: | Alice wants to share a secret with Bob, but she knows that if she explicitly tells it to Bob, Eve somehow will find out (she hears everything). So she and Bob establish a small game which helps them think about the same secret, without saying it. The game goes like this: | ||
| Line 155: | Line 185: | ||
| </file> | </file> | ||
| - | |||
| - | <hidden> | ||
| - | The solution is {{:ic:laboratoare:lab11_sol.zip|here}}. | ||
| - | </hidden> | ||
| - | |||
| - | ==== Exercise 3: RSA parity oracle (4p) ==== | ||
| - | |||
| - | Generate a 1024 bit RSA key pair using the Python's Crypto module. | ||
| - | |||
| - | Write an oracle function that uses the private key to answer the question "is the plaintext of this message even or odd" (is the last bit of the message 0 or 1). Imagine for instance a server that accepted RSA-encrypted messages and checked the parity of their decryption to validate them, and spat out an error if they were of the wrong parity. | ||
| - | |||
| - | Anyways: function returning true or false based on whether the decrypted plaintext was even or odd, and nothing else. | ||
| - | |||
| - | Take the following string and un-Base64 it in your code (without looking at it!) and encrypt it to the public key, creating a ciphertext: | ||
| - | <note> | ||
| - | VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ== | ||
| - | </note> | ||
| - | |||
| - | With your oracle function, you can trivially decrypt the message. | ||
| - | |||
| - | Here's why: | ||
| - | * RSA ciphertexts are just numbers. You can do trivial math on them. You can for instance multiply a ciphertext by the RSA-encryption of another number; the corresponding plaintext will be the product of those two numbers. | ||
| - | * If you double the original plaintext multiply the ciphertext by (2**e)%n). | ||
| - | * If the plaintext after doubling is even, doubling the plaintext didn't wrap the modulus --- the modulus is a prime number. | ||
| - | |||
| - | That means the plaintext is less than half the modulus. | ||
| - | |||
| - | You can repeatedly apply this heuristic, once per bit of the message, checking your oracle function each time. | ||
| - | |||
| - | Your decryption function starts with bounds for the plaintext of [0,n]. | ||
| - | |||
| - | Each iteration of the decryption cuts the bounds in half; either the upper bound is reduced by half, or the lower bound is. | ||
| - | |||
| - | After log2(n) iterations, you have the decryption of the message. | ||
| - | |||
| - | Decrypt the string (after encrypting it to a hidden private key) above. | ||
| - | |||
| - | {{:ic:laboratoare:parity_oracle.zip}} | ||