This shows you the differences between two versions of the page.
ac:laboratoare:07 [2023/11/23 16:31] marios.choudary |
ac:laboratoare:07 [2024/11/14 13:05] (current) dimitrie.valu |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Lab 07 - TOFU-based Authenticated Key Exchange ===== | + | ===== Lab 07 - Whatsapp End-to-end Encryption ===== |
- | For this lab, you will find useful the documentation for openssl, available [[https://www.openssl.org/docs/manmaster/man3/|here]]. | + | In this lab you will implement a simplified version of the Signal Protocol, which is the basis for WhatsApp's end-to-end encryption. |
- | For older versions, such as 1.0.2 you can find it [[https://www.openssl.org/docs/man1.0.2/man3/|here]]. | + | |
- | ==== Task 1: Generate a pair of RSA public/private keys ==== | + | The first versions of Whatsapp protocol were described [[https://cryptome.org/2016/04/whatsapp-crypto.pdf|here]]. A more recent document is available [[https://www.whatsapp.com/security/WhatsApp-Security-Whitepaper.pdf|here]]. |
+ | WhatsApp's security is based on the Signal protocol, which was first used by TextSecure. The Signal protocol is | ||
+ | described in detail in [[https://s3.amazonaws.com/files.douglas.stebila.ca/files/research/papers/EuroSP-CCDGS17-full.pdf|this]] paper. | ||
- | Use these commands to generate a pair of public/private keys: | + | For the Elliptic Curves, you can use [[https://github.com/Muterra/donna25519|this]] library. |
+ | |||
+ | For installation, follow these steps (NOTE: **you can use your ''%%fep%%'' instance via Python3 environments**): | ||
+ | * Install the necessary tools (not necessary on ''%%fep%%''): | ||
<code> | <code> | ||
- | openssl genrsa -out private.pem 2048 | + | sudo apt install build-essential python3-dev |
- | openssl rsa -in private.pem -outform PEM -pubout -out public.pem | + | sudo apt install python3-pip |
+ | </code> | ||
+ | * Use ''%%wget%%'' to download the required zip (find it below) | ||
+ | * Create a Python3 environment, make sure PyPI is up to date and install the required packages: | ||
+ | <code> | ||
+ | python3 -m venv create env | ||
+ | source ./env/bin/activate | ||
+ | pip install --upgrade pip | ||
+ | pip install cryptography donna25519 | ||
</code> | </code> | ||
- | ==== Task 2: Implement DH + RSA signature === | + | **If local installation does not work, use your ''%%fep%%'' instance.** |
- | Modify your DH key exchange implementation (see [[https://ocw.cs.pub.ro/courses/ac/laboratoare/04|lab 4]]) such that when one of the parties (the server) sends its public DH share, | + | === Task === |
- | it also sends a signature over this share using its private RSA key (generated in the previous task). The other party (the client) should have access to the server's public key (e.g. just write it on a file). | + | Find the required zip here - {{:ac:laboratoare:lab07.zip|}}. |
- | On reception of the public DH share from the server, the client should verify the signature from the server by using its public key and should also store this public key and associate it with the IP of the server. | + | Create a common ''%%master_secret%%'' for two clients which communicate through a server. (**TODO 1.1** & **TODO 1.2**) |
+ | Print it on both clients and make sure they both have the same secret. | ||
- | Initial files | + | == How to run == |
- | {{:ac:laboratoare:lab_dh_tofu.zip|}} | + | Open three different terminals. |
- | Note on Makefile. You might need to update the Makefile to suit your openssl version and/or path, e.g.: | + | First terminal (start the server): |
+ | <code>python main_server.py</code> | ||
+ | |||
+ | Second terminal (start the first client and enter ''%%RECV%%'' mode: | ||
<code> | <code> | ||
- | gcc dhe.c -o dhe -L/usr/bin/openssl -lcrypto | + | python main_client.py |
- | gcc dhe_server.c -o dhe_server -L/usr/bin/openssl -lcrypto | + | RECV |
- | </code> | + | |
- | or | + | |
- | <code> | + | |
- | gcc dhe.c -lcrypto -L/usr/lib -o dhe | + | |
- | gcc dhe_server.c -lcrypto -L/usr/lib -o dhe_server | + | |
</code> | </code> | ||
- | Notes: make sure you initialize all objects before use (e.g. the RSA object in the client) and check them after initialization. | + | Third terminal (start the second client and send a message): |
- | For example with this code: | + | |
- | <code C> | + | |
- | CHECK(object!=NULL, "error_on_init_function_x") | + | |
- | </code> | + | |
- | + | ||
- | You might find these methods useful (some of them are given in the provided files, some are part of OpenSSL): | + | |
<code> | <code> | ||
- | EVP_PKEY_set1_RSA | + | python main_client.py |
- | RSASign | + | MSG <id_other_client> Hello! |
- | my_receive | + | |
- | EVP_PKEY_get1_RSA | + | |
- | RSAVerifySignature | + | |
</code> | </code> | ||
- | |||
- | ==== Task 3: Implement DH + RSA + TOFU (bonus) === | ||
- | |||
- | Perform the RSA-based authenticated DH key exchange between the client and server implemented earlier several times. On the first connection, the client should store the public key of the server and associate it with the IP of the server. Then, on subsequent connections, the client must check that the public key of the server matches the one that is stored (if the client already has a public key for the given IP of the server). If it matches, it will use that key for verification of the signature over the DH share of the server. If it doesn't match, it should print an error message and exit. | ||
- | |||
- | This is very similar to what SSH does when connecting to a server using a pair of public/private keys and is known as Trust On First Use (TOFU) authentication. |