# Diffie-Hellman (DH)

### 📌 Classificação

* **Categoria:** Criptografia Assimétrica / Troca de Chaves
* **Criado por:** Whitfield Diffie e Martin Hellman (1976)
* **Contribuições:** Ralph Merkle (Merkle's Puzzles)
* **Base Matemática:** Problema do Logaritmo Discreto
* **Status:** ✅ Padrão global (troca de chaves)

***

### 🎯 Descrição Geral

**Diffie-Hellman (DH)** é um protocolo de **troca de chaves** que permite que duas partes estabeleçam um segredo compartilhado em um canal público **sem nunca terem se comunicado antes**. O segredo compartilhado pode então ser usado para derivar uma chave simétrica para criptografia posterior.

```
Canal Público (Inseguro)
         │
    Alice │ Bob
         │
         ▼
   ┌─────────────┐
   │ DH Exchange │
   └─────────────┘
         │
         ▼
   Segredo Compartilhado (K)
         │
         ▼
   Chave Simétrica (AES, ChaCha20)
```

#### Analogia Clássica (Cores)

> *"Alice e Bob concordam publicamente em uma cor amarela. Cada um escolhe uma cor secreta (Alice: vermelho, Bob: azul). Misturam a cor pública com a secreta (Alice: laranja, Bob: verde). Trocam as misturas. Cada um adiciona sua cor secreta à mistura recebida. Ambos obtêm marrom — a mesma cor secreta."*

***

### ⚙️ Como Funciona (Matemática)

#### Parâmetros Públicos

Todos concordam com:

* **p:** Número primo grande (público)
* **g:** Gerador (raiz primitiva módulo p)

#### Protocolo Passo a Passo

```python
# 1. Alice e Bob escolhem parâmetros públicos (p, g)
p = número_primo_grande
g = gerador

# 2. Alice escolhe um número secreto 'a'
a = random.randint(2, p-2)

# 3. Bob escolhe um número secreto 'b'
b = random.randint(2, p-2)

# 4. Alice calcula A = g^a mod p e envia para Bob
A = pow(g, a, p)  # g elevado a 'a' módulo p

# 5. Bob calcula B = g^b mod p e envia para Alice
B = pow(g, b, p)

# 6. Alice calcula o segredo compartilhado: s = B^a mod p
s_alice = pow(B, a, p)

# 7. Bob calcula o segredo compartilhado: s = A^b mod p
s_bob = pow(A, b, p)

# 8. Ambos chegam ao mesmo segredo!
assert s_alice == s_bob  # (g^(ab) mod p)
```

#### Demonstração Matemática

```
Alice envia: A = g^a mod p
Bob envia:   B = g^b mod p

Alice calcula: s = B^a = (g^b)^a = g^(ba) = g^(ab) mod p
Bob calcula:   s = A^b = (g^a)^b = g^(ab) mod p

Resultado: Ambos têm g^(ab) mod p
```

#### Exemplo Numérico (Pequeno)

```python
# Parâmetros públicos
p = 23
g = 5

# Alice escolhe a = 6
a = 6
A = pow(5, 6, 23)  # 5^6 = 15625, 15625 mod 23 = 8
# Alice envia 8 para Bob

# Bob escolhe b = 15
b = 15
B = pow(5, 15, 23)  # 5^15 mod 23 = 19
# Bob envia 19 para Alice

# Alice calcula segredo: s = 19^6 mod 23
s_alice = pow(19, 6, 23)  # 19^6 mod 23 = 2

# Bob calcula segredo: s = 8^15 mod 23
s_bob = pow(8, 15, 23)    # 8^15 mod 23 = 2

# Ambos têm o segredo 2!
```

***

### 🔐 Variantes do Diffie-Hellman

#### 1. DH Clássico (Finite Field DH)

Baseado em números primos e logaritmos discretos.

```python
# Parâmetros
p = primo_grande (2048-4096 bits)
g = gerador (geralmente 2, 3, 5)

# Segurança depende do tamanho de p
# 2048 bits → ~112 bits de segurança
# 3072 bits → ~128 bits de segurança
# 4096 bits → ~152 bits de segurança
```

#### 2. ECDH (Elliptic Curve Diffie-Hellman)

Versão baseada em curvas elípticas (mais eficiente).

```python
# Curva: y² = x³ + ax + b mod p
# Pontos na curva formam um grupo cíclico

# Alice: escolhe d_a (privado), envia Q_a = d_a × G
# Bob:   escolhe d_b (privado), envia Q_b = d_b × G

# Alice calcula: d_a × Q_b = d_a × d_b × G
# Bob calcula:   d_b × Q_a = d_b × d_a × G

# Segredo compartilhado: coordenada x do ponto resultante
```

#### 3. DHE (Ephemeral Diffie-Hellman)

Chaves temporárias (geradas para cada sessão).

```
Vantagem: Perfect Forward Secrecy (PFS)
- Se a chave de longo prazo for comprometida, sessões anteriores não são afetadas

Uso: TLS (ECDHE), SSH, IPsec
```

#### 4. DH Autenticado (Signed DH)

As chaves públicas são assinadas para prevenir MITM.

```python
# Alice e Bob assinam suas mensagens DH com suas chaves privadas
# Previne ataques de homem no meio (MITM)
```

***

### 🚀 Aplicações do Diffie-Hellman

| Aplicação                | Variante        | Uso                                               |
| ------------------------ | --------------- | ------------------------------------------------- |
| **TLS/HTTPS**            | ECDHE           | Troca de chaves efêmera (Perfect Forward Secrecy) |
| **SSH**                  | DH, ECDH        | Estabelecimento de chave de sessão                |
| **IPsec (VPN)**          | DH, ECDH        | Troca de chaves IKE                               |
| **Signal**               | X3DH            | Extended Triple Diffie-Hellman                    |
| **WhatsApp**             | X3DH            | Criptografia fim-a-fim                            |
| **WireGuard**            | DH (Curve25519) | Troca de chaves da VPN                            |
| **Off-the-Record (OTR)** | DH              | Mensagens instantâneas seguras                    |
| **PGP/GPG**              | DH              | Cifragem de chave de sessão                       |

***

### 💻 Exemplos Práticos

#### Exemplo 1 – DH Clássico em Python

```python
import random

def diffie_hellman(p, g):
    """Implementação simples do DH"""
    # Alice
    a = random.randint(2, p-2)
    A = pow(g, a, p)
    
    # Bob
    b = random.randint(2, p-2)
    B = pow(g, b, p)
    
    # Segredo compartilhado
    s_alice = pow(B, a, p)
    s_bob = pow(A, b, p)
    
    return s_alice, s_bob

# Parâmetros (NIST recomenda)
p = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF
g = 2

s1, s2 = diffie_hellman(p, g)
print(f"Alice: {s1}")
print(f"Bob:   {s2}")
print(f"Segredos iguais: {s1 == s2}")
```

#### Exemplo 2 – ECDH em Python (cryptography)

```python
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization

# Gerar chave privada efêmera (Curve25519)
private_key_alice = ec.generate_private_key(ec.X25519())
private_key_bob = ec.generate_private_key(ec.X25519())

# Chaves públicas
public_key_alice = private_key_alice.public_key()
public_key_bob = private_key_bob.public_key()

# Troca de chaves (ECDH)
shared_secret_alice = private_key_alice.exchange(ec.ECDH(), public_key_bob)
shared_secret_bob = private_key_bob.exchange(ec.ECDH(), public_key_alice)

print(f"Alice: {shared_secret_alice.hex()}")
print(f"Bob:   {shared_secret_bob.hex()}")
print(f"Segredos iguais: {shared_secret_alice == shared_secret_bob}")

# Derivar chave simétrica (HKDF)
import hashlib
import hmac

def hkdf_extract(salt, ikm):
    return hmac.new(salt, ikm, hashlib.sha256).digest()

# Chave AES-256
aes_key = hkdf_extract(b"", shared_secret_alice)
print(f"Chave AES-256: {aes_key.hex()}")
```

#### Exemplo 3 – ECDHE em TLS (OpenSSL)

```bash
# Verificar cifras ECDHE suportadas
openssl ciphers -v | grep ECDHE

# Exemplo de saída:
# ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
# ECDHE-RSA-AES256-GCM-SHA384   TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD

# Testar conexão com ECDHE
openssl s_client -connect google.com:443 -cipher ECDHE-RSA-AES256-GCM-SHA384

# Verificar parâmetros DH usados
openssl s_client -connect google.com:443 -tls1_2 | grep "Server Temp Key"
# Output: Server Temp Key: X25519, 253 bits
```

#### Exemplo 4 – X3DH (Signal Protocol)

```python
# X3DH (Extended Triple Diffie-Hellman) - usado pelo Signal
# Combina três trocas DH para autenticação mútua e PFS

def x3dh(identity_key_alice, signed_prekey_bob, ephemeral_key_alice, one_time_prekey_bob):
    # DH1 = DH(IKA, SPKB)
    dh1 = ecdh(identity_key_alice, signed_prekey_bob)
    
    # DH2 = DH(EKA, IKB)
    dh2 = ecdh(ephemeral_key_alice, identity_key_bob)
    
    # DH3 = DH(EKA, SPKB)
    dh3 = ecdh(ephemeral_key_alice, signed_prekey_bob)
    
    # DH4 = DH(EKA, OPKB) (se one-time prekey existir)
    dh4 = ecdh(ephemeral_key_alice, one_time_prekey_bob)
    
    # Combinar todos os segredos
    shared_secret = KDF(dh1 + dh2 + dh3 + dh4)
    
    return shared_secret
```

#### Exemplo 5 – Implementação DH com Parâmetros Seguros

```python
import secrets
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF

def secure_dh_exchange():
    # Parâmetros recomendados (NIST SP 800-56A)
    # Grupo MODP-2048 (RFC 3526)
    p = int.from_bytes(bytes.fromhex(
        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
        "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
    ), 'big')
    g = 2
    
    # Alice
    a = secrets.randbelow(p-2) + 1
    A = pow(g, a, p)
    
    # Bob
    b = secrets.randbelow(p-2) + 1
    B = pow(g, b, p)
    
    # Segredo compartilhado
    shared_secret = pow(B, a, p)  # = pow(A, b, p)
    
    # Derivar chave simétrica (HKDF)
    hkdf = HKDF(
        algorithm=hashes.SHA256(),
        length=32,
        salt=None,
        info=b"dh-shared-secret"
    )
    aes_key = hkdf.derive(str(shared_secret).encode())
    
    return aes_key
```

***

### ⚠️ Vulnerabilidades e Ataques

#### 1. Man-in-the-Middle (MITM) - O Ataque Clássico

DH **por si só não autentica** as partes. Um atacante pode interceptar e substituir as chaves.

```
Alice → [g^a] → Atacante (Eve) → [g^e] → Bob
Alice ← [g^e] ← Atacante (Eve) ← [g^b] ← Bob

Alice calcula: (g^e)^a = g^(ae)
Bob calcula:   (g^e)^b = g^(be)
Eve calcula:   (g^a)^e = g^(ae) e (g^b)^e = g^(be)

# Eve estabelece segredos diferentes com Alice e Bob!
```

**Mitigação:** Assinar as mensagens DH com chaves de longo prazo (TLS, SSH, IPsec).

#### 2. Logjam Attack (CVE-2015-4000)

Forçar downgrade para grupos DH fracos (export-grade).

```bash
# Vulnerável: grupos DH de 512 bits
# Mitigação: desabilitar export cipher suites
# OpenSSL: !EXPORT
```

#### 3. Small Subgroup Attack

Forçar a chave pública a cair em um subgrupo pequeno.

**Mitigação:** Validar que `1 < B < p-1` e `B^q = 1 mod p` (onde q é o fator primo de p-1).

#### 4. Timing Attack

Implementações que não são de tempo constante podem vazar informações.

**Mitigação:** Usar implementações de tempo constante (libsodium, cryptography).

#### 5. Invalid Curve Attack (ECDH)

Fornecer pontos que não estão na curva legítima.

**Mitigação:** Validar pontos na curva.

***

### 🛡️ Melhores Práticas

#### Tamanhos de Grupo DH

| Segurança | Tamanho p (bits) | Tamanho q (bits) | Uso          |
| --------- | ---------------- | ---------------- | ------------ |
| 80 bits   | 1024 bits        | 160 bits         | ❌ Obsoleto   |
| 112 bits  | 2048 bits        | 224 bits         | ⚠️ Permitido |
| 128 bits  | 3072 bits        | 256 bits         | ✅ Padrão     |
| 192 bits  | 7680 bits        | 384 bits         | ✅ Alto nível |
| 256 bits  | 15360 bits       | 512 bits         | ✅ Máximo     |

#### Grupos Padrão (RFC 3526)

```bash
# Grupos MODP recomendados
# 2048-bit (grupo 14) - mínimo aceitável
# 3072-bit (grupo 15) - recomendado
# 4096-bit (grupo 16) - alta segurança
# 6144-bit (grupo 17) - muito alto
# 8192-bit (grupo 18) - máximo

# Verificar grupo DH do servidor
openssl s_client -connect example.com:443 -cipher DHE-RSA-AES256-GCM-SHA384 2>&1 | grep "Server Temp Key"
```

#### ECDH Curvas Recomendadas

| Curva      | Bits | Segurança | Uso                    |
| ---------- | ---- | --------- | ---------------------- |
| **X25519** | 256  | 128 bits  | ✅ Padrão (recomendado) |
| **P-256**  | 256  | 128 bits  | ✅ Governo US           |
| **X448**   | 448  | 224 bits  | ✅ Alto nível           |
| **P-384**  | 384  | 192 bits  | ✅ Governo US           |
| **P-521**  | 521  | 256 bits  | ✅ Máximo               |

#### Configurações Seguras

```bash
# OpenSSL - Priorizar ECDHE
openssl ciphers -v 'ECDHE:!aNULL:!eNULL:!LOW:!MD5:!EXP:!RC4:!PSK:!SRP:!CAMELLIA'

# Nginx - Priorizar ECDHE
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';

# Apache
SSLCipherSuite 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'

# SSH - Desabilitar DH pequeno
KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256
```

***

### 📜 História do Diffie-Hellman

| Ano      | Evento                                                     |
| -------- | ---------------------------------------------------------- |
| **1976** | Diffie e Hellman publicam "New Directions in Cryptography" |
| **1977** | Merkle descobre ideia similar (Merkle's Puzzles)           |
| **1990** | Primeiros produtos comerciais usando DH                    |
| **1992** | SSH implementa DH                                          |
| **1994** | SSL (precursor do TLS) implementa DH                       |
| **2002** | ECDH é padronizado                                         |
| **2005** | Curve25519 publicada (Bernstein)                           |
| **2011** | X25519 (ECDH com Curve25519) padronizado                   |
| **2014** | Logjam Attack revela fraquezas do DH export-grade          |
| **2018** | TLS 1.3 exige Perfect Forward Secrecy                      |

***

### 🎯 Resumo Rápido

| Ponto                   | Resumo                                             |
| ----------------------- | -------------------------------------------------- |
| **Função**              | Troca de chaves (não cifragem)                     |
| **Base**                | Logaritmo discreto (DH) ou curvas elípticas (ECDH) |
| **Variante moderna**    | ECDH (X25519)                                      |
| **Segurança principal** | Perfect Forward Secrecy (PFS)                      |
| **Ameaça principal**    | MITM (precisa de autenticação)                     |
| **Recomendado**         | ECDHE (TLS), X25519 (SSH, WireGuard)               |
| **Tamanho mínimo**      | 2048 bits (DH), 256 bits (ECDH)                    |

***

### 🔗 Links Úteis

* [RFC 2631 - Diffie-Hellman Key Agreement Method](https://tools.ietf.org/html/rfc2631)
* [RFC 3526 - More Modular Exponential (MODP) DH](https://tools.ietf.org/html/rfc3526)
* [RFC 7748 - Elliptic Curves for Security (Curve25519)](https://tools.ietf.org/html/rfc7748)
* [RFC 8446 - TLS 1.3](https://tools.ietf.org/html/rfc8446)
* [X3DH - Signal Protocol](https://signal.org/docs/specifications/x3dh/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/criptografia/assimetrica/diffie-hellman-dh.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
