2009-08-18 9 views
17

PHP tiene una función uniqid() que genera un tipo de UUID.¿Por qué es MD5'ing un UUID no es una buena idea?

En los ejemplos de uso, se muestra lo siguiente:

$token = md5(uniqid());

Pero en los comentarios, someone says this:

Generación de un MD5 de un identificador único es ingenua y reduce gran parte de el valor de ID únicos, así como proporcionar estenosis significativa (atacable) en el dominio MD5. Eso es una cosa rota profundamente que hacer. El enfoque correcto es usar el ID único en ; ya está orientado para sin colisión.

¿Por qué es esto cierto, si es así? Si un hash MD5 es (casi) único para una identificación única, entonces ¿qué hay de malo en md5'ing un uniqid?

Respuesta

33

Un UUID tiene 128 bits de ancho y tiene singularidad inherente a la forma en que se genera. Un hash MD5 tiene 128 bits de ancho y no garantiza uniquess, solo una baja probabilidad de colisión. El hash MD5 no es más pequeño que el UUID, por lo que no ayuda con el almacenamiento.

Si sabe que el hash procede de un UUID, es mucho más fácil atacarlo porque el dominio de los UUID válidos es realmente bastante predecible si conoce algo sobre la máquina que los genera.

Si necesitara proporcionar un token seguro, entonces necesitaría usar un cryptographically secure random number generator. (1) Los UUID no están diseñados para ser criptográficamente seguros, solo garantizados como únicos. Una sucesión monótonamente creciente limitada por identificadores de máquina únicos (generalmente un MAC) y el tiempo sigue siendo un UUID perfectamente válido, pero altamente predecible si se puede aplicar ingeniería inversa a un único UUID a partir de la secuencia de tokens.

  1. La característica definitoria de un PRNG criptográficamente seguro es que el resultado de una iteración dada no contiene suficiente información para deducir el valor de la siguiente iteración - es decir, no es un estado oculto en el generador que no se revela en el número y no se puede inferir al examinar una secuencia de números del PRNG.

    Si te adentras en la teoría de números, puedes encontrar formas de adivinar el estado interno de algunos PRNG a partir de una secuencia de valores generados. Mersenne Twister es un ejemplo de dicho generador. Tiene el estado oculto de que solía obtener su período largo pero no es criptográficamente seguro: puede tomar una secuencia bastante pequeña de números y usarla para inferir el estado interno. Una vez que haya hecho esto, puede usarlo para atacar un mecanismo criptográfico que depende de mantener esa secuencia en secreto.
4

MD5ing un UUID es inútil porque los UUID ya son únicos y de longitud fija (corta), propiedades que son algunas de las razones por las que las personas a menudo usan MD5 para empezar. Entonces, supongo que depende de lo que planee hacer con el UUID, pero en general un UUID tiene las mismas propiedades que algunos datos que han sido MD5, entonces, ¿por qué ambos?

+1

De hecho, es peor, porque los UUID son únicos, mientras que los hashes MD5 de los UUID no lo son. –

2

Los UUID ya son únicos, por lo que no tiene sentido en MD5'ing de todos modos.

En cuanto a la pregunta de seguridad, en general puede ser atacado si el atacante puede predecir cuál es la próxima identificación única que va a generar.Si se sabe que usted genera sus ID exclusivas a partir de los UUID, el conjunto de posibles identificaciones únicas posteriores es mucho más pequeño, lo que brinda una mejor oportunidad para un ataque de fuerza bruta.

Esto es especialmente cierto si el atacante puede obtener un montón de ID únicas de usted, y de esa manera adivinar su esquema de generación de UUID.

+0

"no tiene sentido": de hecho, es peor que no tener sentido, porque los UUID son únicos, mientras que los hash MD5 de los UUID no lo son. –

2

Version 3 de UUID ya están MD5, por lo que no tiene sentido volver a hacerlo. Sin embargo, no estoy seguro de qué versión de UUID utiliza PHP.

12

Tenga en cuenta que uniqid() no devuelve un UUID, pero una cadena "único" basado en la hora actual:

$ php -r 'echo uniqid("prefix_", true);' 
prefix_4a8aaada61b0f0.86531181 

Si lo hace varias veces, se obtendrán cadenas de salida muy similares y todo el mundo quien esté familiarizado con uniqid() reconocerá el algoritmo de origen. De esta forma, es bastante fácil predecir los próximos identificadores que se generarán.

La ventaja de md5() - ing la salida, junto con una cadena de sal específica de la aplicación o de números aleatorios, es una manera más difícil de adivinar cadena:

$ php -r 'echo md5(uniqid("prefix_", true));' 
3dbb5221b203888fc0f41f5ef960f51b 

diferencia de llanura uniqid(), esto produce muy diferente salidas cada microsegundo. Además, no revela su cadena de "prefijo sal", ni que está usando uniqid() debajo del capó. Sin conocer la sal, es muy difícil (considerar imposible) adivinar la próxima identificación.

En resumen, estoy en desacuerdo con la opinión del comentarista y siempre preferiría la salida md5() -ed en el plano uniqid().

+3

Si necesita que sus identificaciones sean indescifrables, tomar una entrada fácil de adivinar y ofuscarla es _no_ el camino a seguir. –

+0

¿Cómo se puede adivinar la entrada si no se expone la cadena de sal (prefijo utilizado para uniqid())? ¿Puedes explicar tu crítica? –

+1

Hay formas perfectamente buenas de generar ID realmente imposibles de adivinar. Simplemente ofuscando una secuencia fácilmente pronosticada, confías en que nadie descubra el método y tu cadena de sal. Si lo hacen, pueden predecir fácilmente los ID que generarás en el futuro. –

0

Como un lado, MD5 es realmente obsoleto y no se utilizará en nada que valga la protección - PHI, PII o PCI - desde 2010 en adelante. Los federales de EE. UU. Lo han hecho cumplir y cualquier entidad que no cumpla con la ley pagará una gran cantidad de dinero en efectivo.

+0

Sí. El software que usa MD5 para seguridad no se considerará oficialmente después de 2010, pero de manera realista, nadie lo quiere ahora porque se les pedirá que se deshagan de él más adelante (por un valor muy pronto). Entonces, si está vendiendo software o software como un servicio, descartará a algunos clientes simplemente mediante el uso de MD5. Use SHAx, preferiblemente con un gran valor de x. – quillbreaker

+1

Hasta donde yo sé, MD5 nunca se ha incluido en el estándar NIST. Lo que está siendo eliminado por NIST es SHA-1 y básicamente todo lo que tiene 80 bits o menos de seguridad. Además, las compañías que no implementan los estándares NIST no son multadas.Simplemente no pueden obtener la certificación NIST y, por lo tanto, perder clientes que requieren dicha certificación. – Accipitridae

Cuestiones relacionadas