Lab ε - TOFU-based Authenticated Key Exchange

In this lab, we will implement Trust On First Use in a manner similar to that of SSH. We will base our implementation around PyCryptodome - you can find the relevant documentation here.

0. Init

Use these commands to generate a private key and a Diffie-Hellman parameter file:

openssl genrsa -out private.pem 2048
openssl dhparam -out dhparam.pem 2048

The dhparam file will be used as a hardcoded .pem that contains the necessary Diffie-Hellman parameters to generate our DH keys. These values are generally decided upon by convention and are hardcoded - check RFC 7919. An example which can be found there is ffdhe2048.

To better understand its structure, you can use the following commands:

openssl dhparam -in dhparam.pem -text -noout
openssl asn1parse < dhparam.pem

Create a Python environment or use an existing one, then install the required packages:

python3 -m venv create env
source ./env/bin/activate
pip install --upgrade pip
pip install pycryptodome pyasn1 pyasn1-modules

We will use the pyasn1 library to parse the .pem file's binarized DER format more conveniently.

1. Implement DH + RSA signature

Starting from these files, solve the TODO 1 series in dhe_server.py and dhe_client.py.

On the server side, you should:

  • Send the RSA public key to the client.
  • Generate a DH key pair (use the data hardcoded in dhparam.pem) and send the public key to the client.
  • Generate a signature over the RSA and DH public keys (concatenate and hash them, then sign using the RSA private key) and send it to the client. Use this as your guide.
  • Receive the client's DH public key and generate the shared DH secret.
  • Derive a symmetric key from the shared secret. Use HKDF for this.

On the client side, you should:

  • Receive the RSA public key from the server.
  • Receive the server's DH public key.
  • Receive the server's signature over the RSA and DH public keys and verify it using the server's public key.
  • Generate a DH key pair and send the public key to the server.
  • Compute the shared DH secret.
  • Derive a symmetric key from the shared secret.

Generating a signature over the RSA and DH public keys is a way to authenticate the remote host. If the client successfully verifies this signature using the server's public key, then the server is authenticated unless the public key itself has been replaced by the attacker in a man in the middle attack. We will look at a way to (mostly) solve this issue in the next task.

The symmetric key derived from the shared secret will be used to encrypt the communication between the client and server. Although we're stopping the tasks here, this key would be the one that you would use to encrypt and decrypt the communication between the client and server. If you want, you can check the PyCryptodome documentation for more information on how to use AES. To see what ciphers SSH uses, run the following command:

ssh -Q cipher

2. Do you like TOFU?

Now start solving the TODO 2 series by implementing Trust On First Use in dhe_client.py. Do it as follows:

  • Store the public key of the server in a file named known_hosts in the following format (the same way SSH does it):
hostname1 public_key1
hostname2 public_key2
...
  • If the client already has a public key for the given IP of the server, check that the public key of the server matches the one that is stored (if it's a first connection - i.e., First Use - just store the public key and Trust the host).
  • If it matches, print a “connection established” message and proceed to use that key for verification of the signature over the DH share of the server.
  • If it doesn't match, print a suggestive 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.

ac/laboratoare/11.txt · Last modified: 2024/12/12 02:17 by dimitrie.valu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0