---
name: open_key_box
kind: function
lang: go
domain: cybersecurity
version: "1.0.0"
purity: impure
signature: "func OpenKeyBox(kexPub, kexPriv, sealedMsg []byte) ([]byte, error)"
description: "Descifra un sealed box anónimo producido por SealKeyBox usando el par X25519 del destinatario. Devuelve error si la autenticación falla o el mensaje está corrupto."
tags: [messaging, e2e-crypto, crypto, nacl, x25519, sealed-box, key-distribution, e2e-messaging]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports:
  - golang.org/x/crypto/nacl/box
params:
  - name: kexPub
    desc: "Clave pública X25519 del destinatario (exactamente 32 bytes). Debe coincidir con la usada en SealKeyBox."
  - name: kexPriv
    desc: "Clave privada X25519 del destinatario (exactamente 32 bytes). Viene del campo KexPriv de su Identity."
  - name: sealedMsg
    desc: "Sealed box producido por SealKeyBox. Mínimo 48 bytes (32 overhead ephemeral + 16 tag)."
output: "Secreto descifrado (ej. room key de 32 bytes), o error si la autenticación falla, el par de claves no coincide, o el mensaje está truncado."
tested: true
tests:
  - "round-trip con identidad generada"
  - "error con recipientKexPub de longitud incorrecta"
  - "error al abrir con clave equivocada"
  - "error con mensaje truncado"
test_file_path: "functions/cybersecurity/e2e_messaging_crypto_test.go"
file_path: "functions/cybersecurity/open_key_box.go"
---

## Ejemplo

```go
// Receptor obtiene su Identity del almacén seguro
id, _ := loadIdentityFromSecureStorage()
roomKey, err := cybersecurity.OpenKeyBox(id.KexPub, id.KexPriv, sealedMsgFromServer)
if err != nil {
    log.Printf("no se pudo abrir la room key: %v", err)
    return
}
// roomKey lista para usar en SealAEAD / OpenAEAD
```

## Cuando usarla

Al recibir una distribución de clave de sala del servidor: llama OpenKeyBox con el par X25519 propio para recuperar la room key simétrica. Después de obtenerla, úsala en OpenAEAD para descifrar los mensajes de esa sala.

## Gotchas

- El error no distingue entre "clave incorrecta" y "mensaje corrupto" por diseño de seguridad.
- Si `sealedMsg` tiene menos de 48 bytes (overhead mínimo del sealed box), la función devuelve error sin intentar descifrar.
- `kexPub` y `kexPriv` deben ser el par correspondiente: pasar la pubkey de otro usuario con la privkey propia siempre falla.
- La room key recuperada es sensible: no logearla ni incluirla en mensajes de error.
