Projeto 10: Cofre de Segredos e Envelope Encryption em Python 🐍
Escopo do Projeto
Objetivo: Construir um módulo em Python para gerenciamento de dados confidenciais em repouso empregando a arquitetura de Criptografia em Envelope (Envelope Encryption) com AES-256-GCM.
🎯 1. Contexto & Desafio Prático
Em plataformas de nuvem e sistemas de alta escala, criptografar grandes volumes de dados diretamente com uma chave mestra (KEK) gera gargalos e riscos catastróficos em caso de comprometimento da chave. Você implementará o padrão industrial de Envelope Encryption, gerando chaves de dados efêmeras (DEK) para cada registro e encapsulando-as com uma chave mestra de alta segurança.
📋 2. Requisitos Técnicos Obrigatórios
- R1 (Geração de Chaves de Dados - DEK): Implementar a geração segura de chaves efêmeras de 256 bits com
secrets.token_bytes(32)para cada operação de escrita. - R2 (Cifragem de Dados com AES-GCM): Cifrar a carga útil de dados usando AES-256-GCM com IV único de 96 bits gerado pelo sistema operacional e coletar a tag de autenticação.
- R3 (Encapsulamento da DEK com KEK Mestra): Cifrar a DEK efêmera utilizando a chave mestra de criptografia (Key Encryption Key) protegida em memória.
- R4 (Decifragem e Validação de Adulteração): Construir a rotina inversa que decifra a DEK, valida a tag de autenticação dos dados e rejeita imediatamente payloads violados.
📐 3. Diagrama Conceitual & Arquitetura
graph TD
Data["Dados do Usuário (Plaintext)"] -->|Cifra AES-256-GCM| EncData["Ciphertext dos Dados"]
DEK["Chave de Dados Efêmera (DEK - 256 bits)"] -->|Cifra o Dado| EncData
DEK -->|Cifrada pela KEK| EncDEK["DEK Envelopada (Cifrada)"]
KEK["Chave Mestra (KEK - Armazenada em Vault/HSM)"] -->|Protege a DEK| EncDEK
EncData --> Envelope["Envelope Final (Payload JSON com IV, Tag, DEK Cifrada e Dados)"]
EncDEK --> Envelope
style Data fill:#e1f5fe,stroke:#01579b
style DEK fill:#fff3e0,stroke:#e65100
style KEK fill:#f3e5f5,stroke:#7b1fa2
style Envelope fill:#e8f5e9,stroke:#2e7d32 💻 4. Especificação Técnica & Código de Referência
// envelope_vault.py
import os
import json
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
class EnvelopeVault:
def __init__(self, master_kek: bytes):
if len(master_kek) != 32:
raise ValueError("A KEK mestra deve possuir exatamente 256 bits (32 bytes).")
self.kek_cipher = AESGCM(master_kek)
def encrypt_envelope(self, plaintext: bytes) -> str:
# 1. Gerar DEK efêmera de 256 bits
dek = os.urandom(32)
# 2. Cifrar o dado com a DEK via AES-GCM
data_nonce = os.urandom(12)
data_cipher = AESGCM(dek)
ciphertext = data_cipher.encrypt(data_nonce, plaintext, None)
# 3. Cifrar a DEK com a KEK mestra
kek_nonce = os.urandom(12)
encrypted_dek = self.kek_cipher.encrypt(kek_nonce, dek, None)
# 4. Montar o envelope estruturado
envelope = {
"kek_nonce": base64.b64encode(kek_nonce).decode('utf-8'),
"encrypted_dek": base64.b64encode(encrypted_dek).decode('utf-8'),
"data_nonce": base64.b64encode(data_nonce).decode('utf-8'),
"ciphertext": base64.b64encode(ciphertext).decode('utf-8')
}
return json.dumps(envelope)
def decrypt_envelope(self, envelope_json: str) -> bytes:
data = json.loads(envelope_json)
kek_nonce = base64.b64decode(data["kek_nonce"])
encrypted_dek = base64.b64decode(data["encrypted_dek"])
data_nonce = base64.b64decode(data["data_nonce"])
ciphertext = base64.b64decode(data["ciphertext"])
# Recuperar a DEK original decifrando com a KEK
dek = self.kek_cipher.decrypt(kek_nonce, encrypted_dek, None)
# Decifrar os dados confidenciais
data_cipher = AESGCM(dek)
return data_cipher.decrypt(data_nonce, ciphertext, None)
if __name__ == '__main__':
master_key = os.urandom(32)
vault = EnvelopeVault(master_key)
msg = b"Dados Confidenciais de Pagamento: Cartao 4532-XXXX-XXXX-8910"
pack = vault.encrypt_envelope(msg)
recovered = vault.decrypt_envelope(pack)
assert recovered == msg
print("Envelope Encryption validado com sucesso. Dados decifrados com integridade!")
📦 5. Critérios de Avaliação e Entrega
- Arquitetura de duas camadas com separação clara de DEK efêmera e KEK mestra.
- Uso estrito de cifras autenticadas (AES-256-GCM) sem reuso de IVs.
- Payload serializado em JSON com campos codificados em Base64 e validação de tampering.