Las funciones hash criptográficas son algoritmos que toman datos de entrada de cualquier tamaño y producen un valor de salida de tamaño fijo, llamado hash o resumen.

¿Qué es una Función Hash?

Una función hash criptográfica es un algoritmo matemático que convierte datos de entrada en una cadena de caracteres de longitud fija, diseñada para ser irreversible y resistente a colisiones.

Características Principales

Propiedades Fundamentales

  • Determinística: Misma entrada = misma salida
  • Tamaño fijo: Salida de longitud constante
  • Rápida: Cálculo eficiente
  • Irreversible: No se puede obtener entrada desde salida

Propiedades Criptográficas

  • Resistencia a preimagen: Difícil encontrar entrada para hash dado
  • Resistencia a segunda preimagen: Difícil encontrar segunda entrada con mismo hash
  • Resistencia a colisiones: Difícil encontrar dos entradas con mismo hash
  • Avalanche effect: Pequeño cambio en entrada = gran cambio en salida

Algoritmos Principales

MD5 (Message Digest 5)

  • Tamaño: 128 bits (16 bytes)
  • Estado: Obsoleto, no seguro
  • Uso: Solo para checksums no críticos
  • Vulnerabilidades: Colisiones conocidas

SHA-1 (Secure Hash Algorithm 1)

  • Tamaño: 160 bits (20 bytes)
  • Estado: Obsoleto, no recomendado
  • Uso: Legacy systems únicamente
  • Vulnerabilidades: Colisiones teóricas

SHA-2 Family

  • SHA-224: 224 bits (28 bytes)
  • SHA-256: 256 bits (32 bytes) ✅ Recomendado
  • SHA-384: 384 bits (48 bytes)
  • SHA-512: 512 bits (64 bytes) ✅ Recomendado

SHA-3 Family

  • SHA3-224: 224 bits (28 bytes)
  • SHA3-256: 256 bits (32 bytes) ✅ Recomendado
  • SHA3-384: 384 bits (48 bytes)
  • SHA3-512: 512 bits (64 bytes) ✅ Recomendado

BLAKE2

  • BLAKE2b: Hasta 512 bits
  • BLAKE2s: Hasta 256 bits
  • Estado: Moderno, eficiente
  • Uso: Alternativa a SHA-3

Implementación

Python con hashlib

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import hashlib

# SHA-256
data = b"Hello, World!"
hash_sha256 = hashlib.sha256(data).hexdigest()
print(f"SHA-256: {hash_sha256}")

# SHA-512
hash_sha512 = hashlib.sha512(data).hexdigest()
print(f"SHA-512: {hash_sha512}")

# SHA-3
hash_sha3 = hashlib.sha3_256(data).hexdigest()
print(f"SHA3-256: {hash_sha3}")

# BLAKE2
hash_blake2 = hashlib.blake2b(data).hexdigest()
print(f"BLAKE2b: {hash_blake2}")

OpenSSL Command Line

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# SHA-256
echo -n "Hello, World!" | openssl dgst -sha256

# SHA-512
echo -n "Hello, World!" | openssl dgst -sha512

# SHA-3
echo -n "Hello, World!" | openssl dgst -sha3-256

# Verificar archivo
openssl dgst -sha256 -verify public.key -signature signature.bin file.txt

JavaScript (Node.js)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const crypto = require('crypto');

// SHA-256
const hash = crypto.createHash('sha256');
hash.update('Hello, World!');
console.log('SHA-256:', hash.digest('hex'));

// SHA-512
const hash512 = crypto.createHash('sha512');
hash512.update('Hello, World!');
console.log('SHA-512:', hash512.digest('hex'));

Aplicaciones

Integridad de Datos

  • Verificación de archivos: Checksums de archivos
  • Transmisión: Verificar integridad en red
  • Almacenamiento: Detectar corrupción
  • Backups: Verificar respaldos

Autenticación

  • Contraseñas: Almacenar hashes de contraseñas
  • Tokens: Generar tokens únicos
  • Sesiones: Identificar sesiones
  • API Keys: Generar claves de API

Firmas Digitales

  • Hash de mensaje: Resumir mensaje antes de firmar
  • Eficiencia: Firmar hash en lugar de mensaje completo
  • Integridad: Verificar que mensaje no cambió
  • Autenticidad: Confirmar origen del mensaje

Blockchain

  • Merkle Trees: Estructuras de datos
  • Proof of Work: Algoritmos de consenso
  • Block Hashing: Identificar bloques
  • Transaction Hashing: Identificar transacciones

HMAC (Hash-based Message Authentication Code)

¿Qué es HMAC?

HMAC combina una función hash con una clave secreta para crear un código de autenticación de mensajes.

Implementación

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import hmac
import hashlib

# Crear HMAC
key = b"secret-key"
message = b"Hello, World!"
hmac_sha256 = hmac.new(key, message, hashlib.sha256).hexdigest()

# Verificar HMAC
def verify_hmac(key, message, received_hmac):
    expected_hmac = hmac.new(key, message, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected_hmac, received_hmac)

Aplicaciones HMAC

  • API Authentication: Autenticación de APIs
  • JWT: JSON Web Tokens
  • Webhooks: Verificar origen de webhooks
  • Session Management: Gestión de sesiones

Salt y Pepper

Salt

  • Definición: Valor aleatorio agregado a entrada
  • Propósito: Prevenir ataques de diccionario
  • Uso: Almacenar con hash
  • Generación: Criptográficamente seguro

Pepper

  • Definición: Valor secreto agregado a entrada
  • Propósito: Añadir secreto adicional
  • Uso: No se almacena con hash
  • Almacenamiento: Separado y seguro

Implementación con Salt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
import hashlib

def hash_password(password, salt=None):
    if salt is None:
        salt = os.urandom(32)  # 256 bits
    
    # Combinar password + salt
    salted_password = password.encode() + salt
    
    # Calcular hash
    hash_value = hashlib.sha256(salted_password).digest()
    
    return salt + hash_value

def verify_password(password, stored_hash):
    # Extraer salt (primeros 32 bytes)
    salt = stored_hash[:32]
    
    # Calcular hash con salt
    calculated_hash = hash_password(password, salt)
    
    # Comparar
    return calculated_hash == stored_hash

Ataques y Vulnerabilidades

Tipos de Ataques

  • Brute Force: Probar todas las posibilidades
  • Dictionary Attack: Usar diccionarios comunes
  • Rainbow Tables: Tablas precalculadas
  • Collision Attack: Encontrar colisiones

Protecciones

  • Salt: Prevenir rainbow tables
  • Pepper: Añadir secreto adicional
  • Iteraciones: Múltiples rounds (PBKDF2, bcrypt)
  • Algoritmos fuertes: Usar SHA-256 o superior

Mejores Prácticas

  • Algoritmo: Usar SHA-256 o SHA-3
  • Salt: Usar salt único por entrada
  • Iteraciones: Usar PBKDF2 o bcrypt
  • Longitud: Salt de al menos 128 bits

Comparación de Algoritmos

Rendimiento

  • MD5: Más rápido (inseguro)
  • SHA-1: Rápido (inseguro)
  • SHA-256: Moderado (seguro)
  • SHA-512: Más lento (más seguro)
  • SHA-3: Más lento (más seguro)

Seguridad

  • MD5: Inseguro, colisiones
  • SHA-1: Inseguro, colisiones teóricas
  • SHA-256: Seguro, recomendado
  • SHA-512: Muy seguro
  • SHA-3: Muy seguro, resistente a ataques

Recomendaciones

  • Aplicaciones generales: SHA-256
  • Alta seguridad: SHA-512 o SHA-3
  • Legacy systems: Migrar a SHA-256
  • Nuevos proyectos: SHA-3 o BLAKE2

Mejores Prácticas

Selección de Algoritmo

  • SHA-256: Para la mayoría de aplicaciones
  • SHA-512: Para aplicaciones de alta seguridad
  • SHA-3: Para máxima seguridad
  • BLAKE2: Para aplicaciones de alto rendimiento

Implementación

  • Librerías probadas: Usar implementaciones estándar
  • Salt único: Generar salt único por entrada
  • Iteraciones: Usar PBKDF2 o bcrypt para contraseñas
  • Verificación: Implementar verificación segura

Gestión

  • Rotación: Rotar hashes regularmente
  • Monitoreo: Monitorear intentos de ataque
  • Auditoría: Auditorías regulares de seguridad
  • Actualización: Mantener algoritmos actualizados

Conceptos Relacionados

Referencias