# Cómo los agentes de IA y el diseño por contrato detectan errores criptográficos antes de la producción
Los agentes de IA están revolucionando el desarrollo de sistemas seguros: en lugar de escribir código y pruebas manualmente, generan implementaciones basadas en contratos formales. Esto elimina la principal razón por la que el diseño por contrato fracasó: el doble de trabajo. En un proyecto con TRNG de hardware y PKI, se detectaron dos vulnerabilidades críticas precisamente mediante pruebas de contrato que las pruebas unitarias ordinarias habrían pasado por alto.
Por qué las pruebas pasan por alto errores lógicos en criptografía
Las pruebas solo verifican lo que el programador pensó. Si no sabían comprobar el padding en RSA o la calidad de la entropía antes de alimentarla en el DRBG, la prueba no se escribe sola. Así fue como un error de 27 años en OpenBSD y una vulnerabilidad de 16 años en FFmpeg eludieron millones de verificaciones automáticas. Los compiladores y analizadores estáticos son impotentes ante errores lógicos: elegir el modo de cifrado equivocado, omitir comprobaciones de revocación de certificados, usar estándares obsoletos... todo esto pasa desapercibido.
Problema clave: las pruebas reaccionan a la implementación, no a la intención. Los contratos capturan la intención antes de escribir cualquier código. Establecen límites: lo que el sistema debe hacer (postcondiciones), lo que está prohibido (invariantes) y bajo qué condiciones puede invocarse (precondiciones). No es solo documentación: es una especificación ejecutable.
Aquí lo que distingue el enfoque de contratos:
- Formalidad: PRE/POST/INV se escriben en forma legible por máquina, no como comentarios.
- Detección temprana: Las violaciones de contrato fallan de inmediato, no en producción.
- Enfoque en garantías: En lugar de «cómo funciona», «qué se garantiza».
- Fuente única de verdad: El contrato no cambia durante el desarrollo; solo se actualiza si cambian los requisitos.
Cómo el agente de IA se encarga de la segunda mitad del trabajo
El diseño por contrato fracasó en el mainstream por el doble de carga laboral: primero el contrato, luego el código, luego las pruebas. Bajo presión de plazos, los contratos eran las primeras bajas. Hoy, el agente de IA asume la implementación y la generación de pruebas, dejando a los humanos solo la formulación del contrato. Esto cambia la economía: una línea de contrato reemplaza cientos de líneas de código y pruebas.
El proceso es así:
- El humano escribe la invariante:
padding == RSA-PSS | RSA-OAEP; PKCS#1 v1.5 == PROHIBIDO. - El agente genera el módulo CryptoEngine, que solo usa paddings permitidos.
- Simultáneamente, el agente crea una prueba de contrato que intenta usar PKCS#1 v1.5 y espera una excepción.
- Si la prueba falla, el agente corrige la implementación sin tocar el contrato.
- El humano revisa solo 10 líneas de contrato, no 1000 líneas de código.
Ventajas:
- Velocidad: 11 días de trabajo activo en un proyecto embebido fullstack en lugar de meses.
- Fiabilidad: El contrato es el punto focal; los errores en él son más fáciles de detectar que en el código.
- Escalabilidad: Una persona gestiona agentes en roles distintos (codificador, probador, arquitecto).
Caso real: PKI con TRNG de hardware y pruebas de contrato
El proyecto pki-on-box incluye cinco módulos: STM32G431 (TRNG de hardware), daemon de Python (DRBG según NIST SP 800-90A), CryptoEngine (generación de claves), KeyStorage (AES-256-GCM), servicio CA (firma X.509). Cada módulo tiene un contrato formal en las interfaces. Se encontraron dos vulnerabilidades críticas antes del despliegue:
- Padding equivocado: La implementación usó accidentalmente PKCS#1 v1.5 en lugar de RSA-PSS. El ataque Bleichenbacher permite recuperar el texto plano mediante oráculo de padding: la prueba de contrato falló de inmediato.
- Modo AES equivocado: Se seleccionó ECB en lugar de GCM. El contrato requería cifrado autenticado: la prueba falló otra vez.
Métricas del proyecto:
- 131 commits
- 62 pruebas-de-contrato + 15 pruebas-HW
- 3 placas MCU (STM32G474, G431, H750)
- Plataforma objetivo: RK3328 ARM64
- Coste de IA: 1780₽ por 30 sesiones
- Repositorio abierto: github.com/vasilievsv/hw.pki-on-box
Contratos en interfaces: dónde surgen los errores críticos
Los errores lógicos surgen en los límites de módulos. El DRBG genera bytes; CryptoEngine debe saber cómo usarlos. Sin contrato, alguien elige un padding de un ejemplo de StackOverflow. Aquí dos contratos clave del proyecto:
contract: key_generation
PRE:
- DRBG.seeded == true
- algorithm ∈ {RSA-2048, ECDSA-P384}
POST:
- private_key.encrypted(AES-256-GCM)
- public_key = derive(private_key)
INV:
- padding == RSA-PSS | RSA-OAEP
- PKCS#1 v1.5 == PROHIBIDO
contract: certificate_issuance
PRE:
- issuer_ca.valid() && !revoked()
- csr.signature.verify() == true
POST:
- cert.serial.unique()
- cert.signature.verify(issuer_ca.public_key) == true
INV:
- root_ca.offline == true
- cert_chain.depth <= max_path_length
Prueba de contrato para padding:
def test_rejects_pkcs1v15_padding(self, crypto):
priv, pub = crypto.generate_rsa_keypair(bits=2048)
data = b"invariant check"
sig = crypto.sign_data(priv, data)
# PSS debe funcionar
pub.verify(sig, data, padding.PSS(...))
# PKCS1v15 debe fallar
with pytest.raises(Exception):
pub.verify(sig, data, padding.PKCS1v15(), hashes.SHA256())
La prueba no comprueba funcionalidad: verifica el cumplimiento de la invariante. Si cambia el padding, la prueba falla aunque la firma «técnicamente funcione».
Lecciones clave
- Contratos > pruebas: Las pruebas verifican la implementación; los contratos, la intención. Solo las garantías formales capturan errores lógicos.
- IA elimina el doble trabajo: El agente genera código y pruebas desde el contrato; el humano se centra en la especificación.
- Errores críticos en límites: Padding, modos de cifrado, comprobaciones de revocación: todo controlado por invariantes en interfaces de módulos.
- Verificación abierta: Proyecto con TRNG de hardware y pruebas de contrato disponible en repositorio abierto para auditoría.
- Economía temporal: 11 días para un sistema embebido fullstack en lugar de meses, gracias a la división de roles y autogeneración.
— Editorial Team
Aún no hay comentarios.