En una tarjeta de crédito, normalmente encontrará:
- el número , generalmente 16 dígitos;
- la fecha de vencimiento (mes y año, generalmente dentro de los próximos dos años);
- el nombre del titular de la tarjeta;
- el código de seguridad (3 o 4 dígitos).
El problema con la publicación de hashes de dicha información es la vulnerabilidad a una búsqueda exhaustiva: el atacante intenta todas las combinaciones posibles, hasta que una coincida con el valor de hash. Hay dos formas de derrotar tales ataques: manteniendo una gran cantidad de combinaciones y haciendo que el proceso de hashing sea lento.
La ralentización del hash requiere el uso de un salt (para evitar ataques paralelos y precomputaciones), y realizar muchas iteraciones anidadas (tanto como sea posible, siempre que la sobrecarga sea tolerable para su sistema). Hay un arte para eso; Una construcción artesanal descuidada puede ser bastante más débil. Esta parte es muy similar a lo que se hace para las contraseñas, así que redúzcala a la recomendación habitual: use bcrypt . Una buena GPU puede evaluar una función hash de 32 bits como SHA-1 aproximadamente mil millones de veces por segundo; pero al configurar el "factor de costo" de bcrypt, puede reducir esa cifra a, por ejemplo, 100 veces por segundo, sin sobrecargar demasiado su propio sistema.
Ahora veamos el número de combinaciones. El nombre del titular de la tarjeta a menudo se puede adivinar, porque en la base de datos del sitio de un comerciante también registrará el nombre de usuario y posiblemente una dirección de entrega. La fecha de vencimiento es dentro de los próximos dos años (más o menos), por lo tanto, 24 posibilidades. El número de tarjeta generalmente comienza con un identificador de 4 dígitos para el banco, y termina con un dígito de suma de verificación que se calcula de manera determinista a partir de los otros 15. Suponiendo que el atacante intentará, digamos, unos diez bancos distintos, terminará con aproximadamente 10 11 (también conocidos como "cien billones") de números de tarjetas posibles. Sin embargo , si el "número de tarjeta truncado" contiene, digamos, 8 dígitos (el primero y los últimos cuatro dígitos), ese número se reduce a 10 8 (cien millones) .
Si usas bcrypt y el ataque puede ir solo a una velocidad de 100 intentos por segundo, entonces el atacante necesitará un promedio de medio millón de segundos para encontrar el número de tarjeta (eso es aproximadamente 6 días ). Esto puede verse como "suficiente" porque el valor de reventa de un número de tarjeta de crédito robado no es alto (creo que es alrededor de 10 $ como máximo). Para aumentar la resistencia, no agregue el número único, agregue la fecha de vencimiento (x24 en el costo de ataque) y el código de seguridad (x1000).
Entonces, para resumir:
- use bcrypt con un alto recuento de iteraciones (y no pierda el balón en la sal);
- ponga la fecha de caducidad y el código de seguridad en la entrada de hash;
y puede resistir el debilitamiento inducido por el almacenamiento de datos de tarjetas truncadas.