2009-11-03 21 views
6

Ejecuto un sitio web donde marcamos ciertas cuentas como estafadores, y "marca" su cuenta y todas las tarjetas de crédito utilizadas como malas. No almacenamos los valores reales de la tarjeta de crédito, sino que almacenamos un algoritmo de suma de comprobación/MD5 en su lugar.¿Cuál es la mejor manera de determinar números duplicados de tarjetas de crédito sin almacenarlos?

Estamos golpeando colisiones todo el tiempo. Cuál es la mejor forma de almacenar estos valores, no reversible, pero capaz de hacer comparaciones con valores futuros.

pensé MD5 sería la mejor, pero tenemos un debate pasando aquí ...

Respuesta

3

Uso SHA1, colisiones hash aún no se han encontrado.

+3

"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. –

+4

Tienes razón, esto es lo que quise decir. Lo siento, no soy hablante nativo y a veces me resulta difícil expresarme. – Niteriter

+1

SHA-1 está roto: http://www.schneier.com/blog/archives/2005/02/sha1_broken.html, así que use SHA-256 – Jacco

2

Si está encontrando colisiones con MD5, ¿por qué no utilizar un algoritmo mejor como SHA1 or SHA256?

15

Un hash criptográficamente seguro funcionaría. (SHA512 o SHA256 estarían bien)

Sin embargo, usaría una sal bastante secreta que no está almacenada junto con las tarjetas (para evitar cualquier tipo de ataque de tabla de arco iris).

PS:
arco iris ataques mesa contra tarjetas de crédito podrían ser particularlly efectiva, ya que el tamaño total del texto-espacio llano es bastante pequeña debido al número limitado de caracteres, el tamaño fijo, y los dígitos de control .

PPS:
No puede utilizar una sal aleatoria para cada entrada, porque nunca sería capaz para hacer posible comprobar duplicados. Las sales se utilizan para evitar colisiones, mientras que específicamente estamos buscando una colisión en este caso.

+0

Hay discusiones acaloradas sobre eso en SO, pero aparentemente puede almacenar de manera segura la sal junto con la información salada, siempre y cuando la sal sea variada (necesitaría una mesa arcoiris por sal). – PhiLho

+0

Disculpe mi ignorancia, pero ¿por qué no simplemente usar una sal al azar, como se hace aquí si se aprueba "nulo"? http://www.obviex.com/samples/hash.aspx Me falta el sentido de la sal, si no es necesario descifrar (como en el enlace publicado). ¿No es esta una buena clase de ejemplo para usar? – TheSoftwareJedi

+5

No estamos tratando de almacenar y volver a verificar, estamos tratando de hacer coincidencias duplicadas. En ese punto, para verificar un duplicado, debe hacer picadillo con el Número CCard con CADA sal en la base de datos. –

2

MD5 NO es el camino a seguir, ya que está roto. Cita Bruce Schneier: "[w] e ya sabía que MD5 es una función hash rota" y que "ya nadie debería usar MD5".

I.e. use SHA512 o SHA256 como alguien que ya propuso.

+0

SHA1 también está roto: http://www.schneier.com/blog/archives/2005/02/sha1_broken.html – Jacco

1

Usar el hash más fuerte posible suele ser bueno. La velocidad no es esencial y la lentitud en realidad funciona contra cualquiera que intente invertir la fuerza bruta de sus valores hash.

me gusta hidromasaje, personalmente - si está usando PHP echa un vistazo a los algoritmos soportados en the hash function docs

hidromasaje devuelve una cadena de 128 caracteres, pero no tiene que almacenar toda ella necesariamente. Los primeros 32 o 64 caracteres serían suficientes. También podría considerar sha512 o sha284.

4

No es suficientemente seguro usar un buen algoritmo Hash. Si su lista es robada, sus valores hash almacenados se pueden usar para recuperar información de la tarjeta de trabajo. El espacio de esquema real para los números de tarjetas de crédito es lo suficientemente pequeño como para que un atacante determinado también pueda precalcular muchos de los hashes posibles antes de tiempo, y esto puede tener otras implicaciones para su sistema si hay una intrusión o un trabajo interno. .

Le recomiendo que use una sal y también calcule un 2do valor para agregar a la sal basado en una fórmula que involucre cada dígito del número de tarjeta y el primer valor de sal. Esto asegura que si pierde el control de cualquiera de las partes, aún tiene una singularidad razonable que inutiliza la propiedad de la lista.Sin embargo, la fórmula no debe pesar mucho hacia los primeros 6 dígitos de la tarjeta (número BIN), y no se debe almacenar ningún rastro de la fórmula en la misma ubicación que la sal o el hash final.

en cuenta la anatomía de un número de tarjeta de crédito de 16 dígitos:

BIN (Número de identificación del banco) 6 dígitos
9 dígitos Número de cuenta
1 dígito Luhn suma de comprobación

listas BIN son bien conocidos dentro de la industria de procesamiento y no son demasiado difíciles de armar para aquellos que tienen acceso a una lista ilícita de números de tarjetas. El número de BIN válidos se ve disminuido por el espacio asignado para cada emisor.

Visa - Empieza por 4
American Express - Inicia con 34/37
MasterCard - Empieza con 5
Descubrir/CUP - Inicia con 6
Diners Club - Empieza por 35
etc.

Tenga en cuenta que parte de la información de BIN asignada dentro de cada categoría de emisor también es escasa. Si un atacante sabe dónde se encuentra la mayoría de sus clientes, eso reducirá considerablemente la singularidad, ya que la información BIN se asigna por banco. Un atacante que ya tiene una cuenta emitida por un banco pequeño en un vecindario adinerado podría obtener una cuenta y usar el BIN como punto de partida en su propia tarjeta.

El dígito de suma de comprobación se calcula con una fórmula bien conocida, por lo que se puede descartar inmediatamente como fuente de datos únicos.

Armado con un puñado de BINs que vale la pena focalizar, un atacante tiene que verificar 9 dígitos a la vez para cada conjunto de BIN. Esto es 1 Billion Checksums y operaciones Hash por conjunto. No tengo ningún punto de referencia a la mano, pero estoy bastante seguro de que 1 millón de operaciones de Hash por minuto no es irrazonable para MD5 o cualquier sabor de SHA en una máquina suficientemente potente. Esto equivale a menos de un día para descifrar todas las coincidencias en un BIN dado.

Finalmente, también puede considerar almacenar una marca de tiempo o un token de visitante (IP/subred) con sus valores hash. Es bueno capturar números de tarjetas duplicados, pero también considerar las ramificaciones de alguien que rellene su sistema con números de tarjetas falsos. En algún momento debe decidir sobre una solución de compromiso entre bloquear números de tarjetas que usted sabe que son inválidas, y también darse un mecanismo para identificar y reparar el uso indebido.

Por ejemplo, un empleado descontento podría estar robando información de la tarjeta por su cuenta y luego usar su mecanismo de hash en su contra insertando hashes válidos en la lista negra de su número de tarjeta para bloquear la repetición del negocio. Es bastante caro deshacer esto si solo está almacenando un hash, todo es opaco una vez que se ha convertido en un hash. Con esto en mente, concédete un método para identificar la fuente del hash también.

+0

Tal vez soy ingenuo, pero sin la información del nombre en la tarjeta o la fecha de vencimiento, ¿qué puedo hacer? ¿alguien lo hace con solo el número de tarjeta? – dlamblin

+0

el nombre del titular de la tarjeta no se usa en el momento de la venta por los procesadores para decidir si rechaza o aprueba una transacción. puede ser utilizado posteriormente por cualquier número de partes en la cadena de procesamiento o por el software que lo retransmitió. por lo tanto, no se puede utilizar como barrera o como protección en el momento de un intento de transacción. la fecha de vencimiento sí importa, pero algunos ISO/procesadores proporcionan búsquedas en vivo para transacciones de prueba. esto hace posible aplicar fuerza bruta los ~ 120 meses a plazo para la fecha de caducidad de una carta determinada si tiene acceso a dicha cuenta de prueba. – meklarian

4

Quizás pueda almacenar dos hash diferentes del número de tarjeta. Las posibilidades de que ambos hashes generen colisiones son prácticamente nulas.

+0

esta es una idea realmente interesante. Gracias por compartirlo. – JustinP

1

No se moleste en hacer sales, solo use HMAC. Sé que es una especie de abuso, pero luego obtienes un hash con clave decente, por lo que puedes evitar colisiones y ataques de tablas del arco iris.

Lo bueno aquí es que incluso si la llave se filtra, nadie puede descifrarla. Lo mejor que funciona para HMAC es la fuerza bruta. En realidad, la clave aquí es una sal como se mencionó anteriormente.Lo bueno de esto es que el algoritmo es un poco mejor que el salado habitual hecho por la mayoría de los programadores que no son de seguridad.

2

Como Henri ya se ha mencionado anteriormente (+1), la solución correcta es usar el Código de autenticación de mensajes como HMAC con una clave secreta. Esta es exactamente la "sal secreta" que alguien mencionó anteriormente. (Por cierto, las sales son siempre públicas).

Utilice la construcción estándar como HMAC-SHA-256 (RFC2104, FIPS-198a), mantenga la clave en secreto y almacene los resultados (etiquetas de autenticación) en una base de datos.

El tamaño de resumen más grande (256 bits) de SHA-256 debe evitar cualquier colisión, SHA-256 es una función hash bastante buena y la probabilidad de colisiones aleatorias es 2^-128, por lo que si alguna vez se encuentra con una colisión en tu sistema, por favor, ¡házmelo saber! :)

3

Las personas que señalan que un hash está "roto" carecen de sentido, quizás regurgitando algo que han escuchado sin entender lo que significa. Cuando las personas hablan de que los hash están "rotos", normalmente significan que es posible generar fácilmente una carga alternativa que se compute con el mismo hash.

Esto 'rompe' el hash pero solo con el propósito específico de usar un hash para verificar que los datos sean los que se supone que son.

Eso no es importante aquí, es decir, alguien que logra crear un flujo de datos alternativo que pasa al hash hasta el mismo valor que una de las tarjetas de crédito no logra nada significativo o útil en términos de un vector de ataque.

El riesgo con los valores hash aquí es que el espacio problemático para los números de tarjetas de crédito es bastante bajo y las tablas rainbow para ellos serían bastante económicas y fáciles de generar.

Agregar una sal añadiría un poco de protección contra tablas rainbow ya generadas para números de tarjetas puros, pero la medida en que ofrece una protección real depende de cuán 'secreta' permanecería la sal en caso de que se vea comprometida. Si la sal está expuesta, entonces las nuevas tablas de arcoiris pueden generarse de forma barata y todo habrá terminado.

Dado que la sal debe estar disponible para que la aplicación realice comprobaciones en la lista negra, existe una buena posibilidad de que alguien que comprometa los datos de la lista negra también pueda acceder a la sal. Si tiene varios servidores, puede mitigar eso hasta cierto punto, asegurando que tanto la sal como los datos no estén en el mismo 'lugar', por lo que una exposición de un servidor no le dará a alguien todas las partes que necesita. (De manera similar para las copias de seguridad, no almacene los datos y la sal en el mismo medio donde alguien puede alejarse con una cinta y obtener todo). La sal solo agrega algo de protección mientras es secreta (en este tipo de uso).

Si tiene los recursos para hacerlo de forma segura, entonces creo que ese es el camino a seguir. Si está obteniendo un número significativo de colisiones en cualquier función hash razonable, debe estar haciendo mucho volumen. (De hecho, estoy muy sorprendido de que las colisiones sean un problema incluso entonces, cualquier función hash razonable debería proporcionar resultados diversos en un espacio con problemas pequeños como este).

2

Como han dicho otros, HMAC debería ser el camino a seguir.

HMAC-SHA-256 con una llave adecuada debe:

  1. evitar colisiones.
  2. Evite la recuperación del número de tarjeta de crédito del valor almacenado.
  3. 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 :-)

Cuestiones relacionadas