- Seguridad y Gobernanza Liderada por CISO/
- Análisis de Seguridad y Asesorías/
- Hashing de Datos de Baja Entropía y Tarjetas de Crédito en APAC/
Hashing de Datos de Baja Entropía y Tarjetas de Crédito en APAC
Tabla de contenidos
He aquí un hecho incómodo: aplicar un hash no es lo mismo que proteger. Usted puede almacenar el hash SHA-256 de un número de tarjeta de crédito, cumplir plenamente con PCI DSS y aun así tener efectivamente ninguna protección, porque el valor que ha procesado simplemente no contiene suficiente entropía para resistir la fuerza bruta.
Esto despista a equipos de ingeniería por lo demás cuidadosos porque el hashing se siente seguro. El hash es unidireccional, el original no puede recuperarse invirtiendo la función, así que seguramente los datos están protegidos. El fallo no está en el hash. El fallo está en lo que le ha dado de comer.
El problema de la entropía, en números reales #
Un número de tarjeta de 16 dígitos no es aleatorio. Su estructura es pública y fija:
- Los primeros 4 a 6 dígitos son el Número de Identificación del Emisor (IIN): el prefijo del banco, totalmente público.
- El último dígito es una suma de comprobación, calculada por el algoritmo de Luhn, una fórmula publicada en 1954. No es secreta; es detección de errores.
Ahora enmascare el PAN como PCI DSS permite habitualmente: los primeros 4 a 6 dígitos y los últimos 4 visibles, con los 6 a 8 intermedios ocultos:
4532 AAXX XXXX 1234
Con solo 4 dígitos conocidos del IIN, lo que queda desconocido son 8 dígitos, o como mucho 100.000.000 valores posibles. Al aplicar la suma de Luhn solo sobrevive 1 de cada 10. Su espacio real de búsqueda es de 10 millones de valores. Eso no es una contraseña. Es una lista muy pequeña.
¿Qué tan rápido se pueden probar 10 millones de hashes? #
Aquí las cosas empeoran. SHA-256 es rápido por diseño. Está construido para verificación de integridad a velocidad gigabit, no para guardar secretos. Los benchmarks públicos de cracking con GPU son reproducibles:
| Hardware | Rendimiento aproximado SHA-256 |
|---|---|
| 1× GPU RTX 4090 | ~8.500 millones de hashes/segundo |
| Clúster 4× RTX 4090 | ~34.000 millones de hashes/segundo |
| Clúster 8× RTX 4090 | ~68.000 millones de hashes/segundo |
Diez millones de intentos divididos entre 8.500 millones por segundo ronda una milésima de segundo. En una sola GPU doméstica. Incluso un único equipo con GPU puede usar una tabla rainbow para “deshacer” el hash de un número de tarjeta en un abrir y cerrar de ojos.
La conclusión es tajante: conforme no es igual a seguro. En campos de baja entropía, incluso SHA-2 (o SHA-3) no es seguro, aunque sea conforme. La función es unidireccional; simplemente es trivialmente agotable cuando el espacio de entrada es diminuto. Cambiar SHA-256 por SHA-512 o SHA-3 no arregla esto, porque son igual de rápidos.
Qué permite realmente “ser conforme” #
PCI DSS no le dice realmente que procese los PAN con SHA-256. El requisito 3.5 dice que debe volver el PAN ilegible usando criptografía fuerte, que menciona explícitamente hashes con clave y cifrado, y señala que un índice procesado con salt es aceptable cuando el salt es secreto y el hash no es reversible en la práctica. El problema es que un SHA-256 desnudo, sin salt, sobre un espacio de 10 millones de valores es, en la práctica, reversible por agotamiento, así que incumple la intención del requisito aunque la casilla de la lista pase.
El enmascaramiento (mostrar los primeros 4-6 y/o los últimos 4) es un control aparte: protege lo que ve un operador, no lo que usted almacena. Los dos se confunden fácilmente, y esa confusión es cómo terminan en producción PANs enmascarados pero con hash desnudo.
Cómo proteger bien este tipo de datos #
La solución es tratar los campos de baja entropía con el mismo respeto que una contraseña, porque matemáticamente son igual de débiles. Las opciones, por orden de preferencia:
- No almacenarlo en absoluto. Tokenice el PAN y guarde el número real en una bóveda o HSM separados. Si nunca almacena el valor, no hay nada que forzar.
- Hashing con clave (HMAC) y un pepper secreto. Si debe indexar por PAN, use un HMAC con una clave de alta entropía guardada fuera de la base de datos. Sin la clave, la fuerza bruta es computacionalmente inviable sin importar la entropía de entrada.
- Hashing de contraseñas intensivo en memoria. Donde necesite proteger el valor con el valor a secas, use Argon2id (RFC 9106) o scrypt con un salt aleatorio por valor y parámetros ajustados para que cada intento cueste tiempo y memoria reales. Argon2id con, digamos, 64 MB de coste de memoria convierte esa búsqueda exhaustiva de 0,001 segundos en meses de tiempo de GPU.
- Salts y peppers en todas partes. Un salt aleatorio por valor vence las tablas rainbow precalculadas; un pepper secreto vence por completo los ataques fuera de línea mientras siga siéndolo.
La OWASP Password Storage Cheat Sheet y NIST SP 800-63B recomiendan ambas funciones intensivas en memoria para secretos de baja entropía por exactamente esta razón.
La lección más allá de las tarjetas #
Esto aplica a todo identificador de formato fijo con entropía limitada: números de identidad nacional, teléfonos, fechas de nacimiento e incluso claves API con generación pobre. Si el espacio de entrada es pequeño, la velocidad de la función hash es su enemiga, y “conforme” no es sinónimo de “seguro”.
Nuestra Revisión de Seguridad de APIs y Aplicaciones examina cómo su código almacena y transmite realmente los valores sensibles, y le diremos sin rodeos dónde una casilla superada está dejando datos reales expuestos.