Como han dicho otros, HMAC debería ser el camino a seguir.
HMAC-SHA-256 con una llave adecuada debe:
- evitar colisiones.
- Evite la recuperación del número de tarjeta de crédito del valor almacenado.
- Evite que un atacante realice el mismo cálculo (en todos los números de tarjeta de crédito posibles, para encontrar un valor que coincida).
Pero hay una cosa más importante:
Es con buena razón de que no va a almacenar los números de tarjetas de crédito. Incluso si pudiera estar 100% seguro de que está utilizando el cifrado adecuado, probablemente aún no almacene números de tarjetas de crédito. ¿Por qué? Por un lado, porque la clave podría filtrarse.
Así que almacena hash, para que el número de tarjeta de crédito no se pueda recuperar. ...¿Derecha?
Bueno, si utiliza un hash simple, una tabla simple de arcoíris con hash de todos los números de tarjetas de crédito posibles regala todos los datos originales que presumiblemente no almacenó. Oops. Pero esto ya lo sabías.
Así que tratamos de hacerlo mejor. Digamos que usar sales individuales es mejor, y usar HMAC es el mejor enfoque que conocemos.
cuenta la situación siguiente:
- tomar un número de tarjeta de 16 dígitos.
- Los primeros 6 dígitos (número de identificación del banco) se adivinan probando algunos BIN comunes.
- Los últimos 4 dígitos son visibles en el número de tarjeta enmascarada, que puede almacenar. (Es posible que no tenga esto almacenado, lo que ayuda.)
- Se calcula 1 dígito (Luhn).
Esto deja 5 dígitos para ser forzado por fuerza bruta. Eso es unos escasos 100 000 intentos.
Si hemos utilizado las sales individuales, se ha acabado el juego. Simplemente podemos usar la fuerza bruta de cada número de tarjeta individual a un promedio de 50,000 intentos.
Si hemos usado HMAC, parece que estamos a salvo. Pero recuerde ... elegimos no almacenar números de tarjeta cifrados, porque incluso con una encriptación perfecta, la clave podría filtrarse. Adivina qué. Nuestra clave HMAC se puede filtrar de la misma manera. Con la llave, de nuevo, podemos usar la fuerza bruta de cada número de tarjeta individual a un promedio de 50,000 intentos. Entonces, una clave filtrada nos da los números de las tarjetas de crédito, del mismo modo que si hubiéramos almacenado números de tarjetas encriptados.
Como tal, debido a la baja entropía de los números de tarjetas de crédito, almacenar hashes no agrega mucha seguridad en comparación con los valores cifrados (sin embargo, PCI limita el requisito de rotación de claves al cifrado).
Un poco de perspectiva:
Ok, estamos asumiendo una clave de filtrado aquí. Extremo. Pero, nuevamente, también lo hace PCI como parte de su razonamiento para prohibirle el almacenamiento de números de tarjetas de crédito, por lo que al menos deberíamos considerarlo.
Cierto, no tomé en cuenta las múltiples conjeturas para encontrar el BIN. Sin embargo, debería ser una pequeña constante. O podríamos limitarnos a un BIN.
Definitivamente, un auditor PCI puede ser más indulgente que yo.
Sí, si no almacena el número de la tarjeta enmascarada, es un factor 10'000 más seguro. Esto ayuda mucho. Úselo para su ventaja. Aún así, si 50K intentos son factibles, 500M también puede ser factible. No es suficiente hacer que considere los datos como seguros, en el contexto de una clave comprometida.
Conclusión:
Uso de HMAC-SHA-256. Comprenda el riesgo. Almacenar lo menos posible. Protege tus llaves atentamente. Gaste una fortuna en un Módulo de seguridad de hardware :-)
"Aún no se han encontrado colisiones hash"? Eso es muy poco probable. Lo que quiso decir es probablemente "sin ataque de colisión" aún se conoce. Las colisiones siempre pueden ocurrir cuando se reducen grandes cantidades arbitrarias de datos a un valor de tamaño fijo. –
Tienes razón, esto es lo que quise decir. Lo siento, no soy hablante nativo y a veces me resulta difícil expresarme. – Niteriter
SHA-1 está roto: http://www.schneier.com/blog/archives/2005/02/sha1_broken.html, así que use SHA-256 – Jacco