--- 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.