# Diffie-Hellman Key Exchange

Last modified: 2023-11-05

Diffie-Hellman key exchange is a mathematical method for exchaning cryptographic key securely. The goal is to securely communicate with each other while preventing man-in-the-middle attack. It is also used for cryptographic algorithms such as AES, DES.

## Overview

DH calculates shared secrets with public keys and secret keys. Below is a Python script to calculate shared secrets for A and B. These (`ss_A`

and `ss_B`

) should be the same value with each other.

```
# Calculate public keys (A, B)
# p: public key (a prime number)
# g: public key (a primitive root modulo `p`)
# a, b: secret key
A = pow(g, a, p)
B = pow(g, b, p)
# Calculate shared secret
ss_A = pow(A, b, p)
ss_B = pow(B, a, p)
# Shared secrets should be the same value each other
print(ss_A == ss_B) # True
print(pow(pow(g, a, p), b, p) == pow(pow(g, b, p), a, p)) # True
```

## Key Exchange Flow using OpenSSL

Reference: https://tryhackme.com/room/cauldron#

Assume that Alice and Bob want to communicate each other secretly. In such a situation, we can use the Diffie-Hellman key exchange.

### 1. Generate DH Params for Key Agreement

First of all, we need to generate Diffi-Hellman parameters which include two prime numbers `p`

and `g`

. These parameters are used for calculating shared secret for Alice and Bob.

We can use `openssl`

with `dhparam`

option for doing that.

```
# 2048: 2048-bit
openssl dhparam -out dhparams.pem 2048
```

For more robustness, we can use more longer bit length such as `4096`

instead of `2048`

, but it requires more computational power and time.

### 2. Generate Private Keys

Next, generate private keys for both Alice and Bob. We can use `genpkey`

option of `openssl`

for doing that.

```
# Alice
openssl genpkey -paramfile dhparams.pem -out alice_private.pem
# Bob
openssl genpkey -paramfile dhparams.pem -out bob_private.pem
```

### 3. Generate Public Keys

Using the private keys, we also generate public keys.

```
# Alice
openssl pkey -in alice_private.pem -pubout -out alice_public.pem
# Bob
openssl pkey -in bob_private.pem -pubout -out bob_public.pem
```

### 4. Generate Shared Secret

This time, Alice and Bob generate shared secrets using each other’s public key. Each shared secret will be the same (`alice_shared_secret == bob_shared_secret`

).

```
# Alice
openssl pkeyutl -derive -inkey alice_private.pem -peerkey bob_public.pem -out alice_shared_secret.bin
# Bob
openssl pkeyutl -derive -inkey bob_private.pem -peerkey alice_public.pem -out bob_shared_secret.bin
```

By doing this, it’ll be difficult for an eavesdropper to recreate shared secrets unless he knows Alice and Bob’s private keys because.

### 5. Use Shared Secret for Secure Communication

Now Alice and Bob can use this shared secret with cryptographic algorithm such as **AES**.

Assume Alice encrypts `hello.txt`

which contains greeting message and sends the encrypted file to Bob. Then Bob decrypts the encrypted file with the same cryptographic algorithm and read the message.

```
# Encryption: Alice encrypts `hello.txt` with AES.
openssl enc -aes-256-cbc -pass file:alice_shared_secret.bin -in hello.txt -out encrypted.enc
# Decryption: Bob decrypts the encrypted `encrypted.enc` with the same algorithm.
openssl aes-256-cbc -d -in hello_encrypted.enc -pass file:bob_shared_secret.bin -out decrypted.txt
```

Unless the shared secret is published or stolen, their secret messages will never be seen by eavesdroppers.

## Decrypt Secret Message using Private Key and Public Key

If we have a private key and a public key with some reason, we can decrypt a secret message by recreating a shared secret using these keys.

### 1. Generate Shared Secret

Using a private key and a public key, we can generate a shared secret which is used for decrypting an encrypted message.

```
openssl pkeyutl -derive -inkey private.key -peerkey public.key -out shared_secret
```

### 2. Decrypt a Secret Message

Now we can decrypt a secret message using the shared secret.

```
openssl aes-256-cbc -d -in encrypted.enc -pass file:shared_secret -out decrypted.txt
```