Saltar a contenido

Capítulo 18 — Criptografía y Seguridad Informática

Objetivos de aprendizaje

  • Distinguir cifrado simétrico/asimétrico, hashing y firmas.
  • Implementar y, sobre todo, usar correctamente primitivas criptográficas.
  • Escribir código de tiempo constante y generar aleatoriedad segura.
  • Conocer ataques (canal lateral) y defensas.

Regla de oro de la criptografía

No implementes tu propia criptografía para producción. Estos ejercicios son para entender las primitivas; en sistemas reales usa libsodium, OpenSSL o BoringSSL, auditadas por expertos. Un error sutil = sistema roto.


18.1 Fundamentos

Objetivos de seguridad (CIA): Confidencialidad, Integridad, Autenticidad. El principio de Kerckhoffs: la seguridad debe residir en la clave, no en el secreto del algoritmo.


18.2 Cifrado simétrico

Misma clave para cifrar y descifrar. Estándar actual: AES (128/256 bits) en modos de cifrado autenticado (AES-GCM, ChaCha20-Poly1305).

// XOR cipher: SOLO didáctico. Inseguro, pero ilustra el concepto de cifrado en flujo.
void xor_cipher(uint8_t *datos, size_t n, const uint8_t *clave, size_t k) {
    for (size_t i = 0; i < n; i++) datos[i] ^= clave[i % k];
}

Modos y nonces

Nunca uses ECB (filtra patrones). Usa AEAD (GCM/Poly1305) y nunca repitas el nonce con la misma clave.


18.3 Cifrado asimétrico

Clave pública/privada. RSA (basado en factorización) y curvas elípticas (ECC, más eficiente). Permiten intercambio de claves (Diffie-Hellman) y firma digital.


18.4 Funciones hash

Resumen de tamaño fijo, unidireccional y resistente a colisiones. SHA-256, SHA-3, BLAKE⅔. Para contraseñas, hashes lentos y con sal: Argon2, scrypt, bcrypt — nunca SHA crudo.

// HMAC: autenticación de mensajes con clave (esquema)
// HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m))

18.5–18.6 ECC, autenticación y certificados

Curvas modernas: Curve25519 (X25519 para intercambio, Ed25519 para firma). Certificados X.509 y PKI: cadena de confianza que respalda TLS (cap. 13, 28).


18.7 Código de tiempo constante

Comparar secretos con memcmp filtra información por canal lateral de tiempo (termina antes en el primer byte distinto). Compara en tiempo constante:

int ct_memcmp(const void *a, const void *b, size_t n) {
    const uint8_t *x = a, *y = b; uint8_t d = 0;
    for (size_t i = 0; i < n; i++) d |= x[i] ^ y[i];  // sin retorno anticipado
    return d;   // 0 si iguales
}

18.8 Aleatoriedad segura

// NO uses rand() para claves. En Linux/POSIX moderno:
#include <sys/random.h>
uint8_t clave[32];
getrandom(clave, sizeof clave, 0);   // o getentropy()

18.9–18.11 Ataques, aplicaciones y librerías

  • Ataques: fuerza bruta, canal lateral (tiempo, caché, potencia), padding oracle, repetición.
  • Aplicaciones: gestores de contraseñas, cifrado de archivos, firma de software.
  • Librerías: libsodium (la recomendada por su API a prueba de errores), OpenSSL, BoringSSL, mbedTLS (embebidos).

Conexión con la actualidad

La criptografía vive su mayor transición en décadas: la criptografía post-cuántica (PQC). En agosto de 2024 el NIST estandarizó los primeros algoritmos resistentes a computadores cuánticos — ML-KEM (Kyber), ML-DSA (Dilithium) y SLH-DSA (SPHINCS+) — y las grandes implementaciones en C (OpenSSL 3.x, BoringSSL, liboqs) ya los incorporan; navegadores y Cloudflare han desplegado X25519+Kyber híbrido en TLS. Paralelamente, los ataques de canal lateral siguen siendo críticos: Spectre/Meltdown y sus sucesores demostraron que incluso código criptográficamente correcto puede filtrar secretos por la microarquitectura, lo que ha hecho del código de tiempo constante una disciplina obligatoria. Para auditar fugas de tiempo existen herramientas como dudect y ctgrind. La lección del curso: usa bibliotecas auditadas, pero entiende lo suficiente para usarlas bien.


Ejercicios

Ejercicio 18.1 — Cifrado César y Vigenère ★

Implementa y rompe ambos por análisis de frecuencias (didáctico).

Ejercicio 18.2 — SHA-256 con librería ★★

Calcula el hash de un archivo usando libsodium/OpenSSL y verifícalo con sha256sum.

Ejercicio 18.3 — Comparación de tiempo constante ★★★

Mide experimentalmente la diferencia de tiempo entre memcmp y ct_memcmp al comparar tokens secretos.

Ejercicio 18.4 — Cifrado de archivos con libsodium ★★★★

Cifra y descifra un archivo con crypto_secretstream (AEAD), gestionando clave y nonce correctamente.


Referencias

  • Serious Cryptography (Jean-Philippe Aumasson), 2.ª ed.
  • Cryptography Engineering (Ferguson, Schneier, Kohno).
  • libsodium — la API recomendada.
  • NIST FIPS 203/204/205 (ML-KEM, ML-DSA, SLH-DSA), 2024.