---
name: envelope_encrypt
kind: function
lang: py
domain: cybersecurity
version: "1.0.0"
purity: impure
signature: "def envelope_encrypt(plaintext: bytes, master_key: bytes) -> bytes"
description: "Cifra datos usando patron Envelope Encryption con AES-256-GCM. Genera una file key aleatoria (DEK), cifra los datos con ella, luego cifra la file key con la master_key (KEK). Retorna un envelope binario con magic b'OVE1'."
tags: [encryption, aes, gcm, envelope-encryption, dek, kek, cryptography, cybersecurity]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [cryptography, secrets, struct]
params:
  - name: plaintext
    desc: "datos a cifrar con AES-256-GCM"
  - name: master_key
    desc: "clave maestra KEK de 32 bytes para cifrar la file key"
output: "envelope binario con magic b'OVE1' conteniendo datos cifrados"
tested: true
tests:
  - "encrypt → decrypt roundtrip"
  - "datos vacios"
  - "datos grandes"
  - "ciphertext tiene magic correcto"
  - "ciphertext es distinto cada vez"
test_file_path: "python/functions/cybersecurity/envelope_encrypt_test.py"
file_path: "python/functions/cybersecurity/cybersecurity.py"
---

## Ejemplo

```python
import secrets
from cybersecurity import envelope_encrypt, envelope_decrypt

master_key = secrets.token_bytes(32)  # 256-bit KEK
plaintext = b"datos confidenciales"

ciphertext = envelope_encrypt(plaintext, master_key)
# ciphertext[:4] == b"OVE1"

recovered = envelope_decrypt(ciphertext, master_key)
# recovered == plaintext
```

## Formato del envelope

```
Magic    (4B): b"OVE1"       identificador de formato
Version  (1B): 0x01          version del protocolo
Reserved (1B): 0x00          reservado para uso futuro
EFK_len  (2B): big-endian    longitud de encrypted_file_key
KIV_len  (2B): big-endian    longitud de key_iv
DIV_len  (2B): big-endian    longitud de data_iv
--- header: 12 bytes total ---
Encrypted File Key (variable, incluye GCM auth tag de 16B)
Key IV             (12B)
Data IV            (12B)
Encrypted Content  (variable, incluye GCM auth tag de 16B)
```

## Notas

Implementacion original inspirada en OpenViking `openviking/crypto/encryptor.py` (AGPL-3.0). Reimplementada desde cero.

- La file key (DEK) es de 32 bytes generados con `secrets.token_bytes` (CSPRNG).
- Tanto el cifrado de datos como el de la file key usan AES-256-GCM con IVs de 12 bytes.
- El GCM auth tag (16 bytes) garantiza autenticidad e integridad.
- `master_key` debe ser de exactamente 32 bytes para AES-256.
- Requiere `cryptography` instalado: `uv add cryptography`.
