php - encrypt - ¿Por qué no es una buena idea MD5''ing un UUID?
md5 php online (6)
Los UUID ya son únicos, por lo que no tiene sentido en MD5''ing de todos modos.
Con respecto 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.
PHP tiene una función uniqid () que genera un tipo de UUID.
En los ejemplos de uso, muestra lo siguiente:
$token = md5(uniqid());
Pero en los comentarios, alguien dice esto :
Generar un MD5 a partir de un ID único es ingenuo y reduce gran parte del valor de los ID únicos, además de proporcionar una estenosis significativa (atacable) en el dominio MD5. Eso es algo profundamente roto para hacer. El enfoque correcto es usar la identificación única por sí mismo; ya está orientado para no 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?
MD5ing un UUID no tiene sentido porque los UUID ya son únicos y de longitud fija (corta), propiedades que son algunas de las razones por las cuales 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?
Por otro lado, MD5 es en realidad obsoleto y no debe utilizarse en nada que valga la pena proteger (PHI, PII o PCI) a partir de 2010. 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.
Tenga en cuenta que uniqid()
no devuelve un UUID , sino una cadena "única" en función de la hora actual:
$ php -r ''echo uniqid("prefix_", true);''
prefix_4a8aaada61b0f0.86531181
Si lo hace varias veces, obtendrá cadenas de salida muy similares y todos los que uniqid()
familiarizados con uniqid()
reconocerán el algoritmo de origen. De esta forma, es bastante fácil predecir los próximos identificadores que se generarán.
La ventaja de md5 () - la salida, junto con una cadena de sal específica de la aplicación o un número aleatorio, es una manera más difícil de adivinar la cadena:
$ php -r ''echo md5(uniqid("prefix_", true));''
3dbb5221b203888fc0f41f5ef960f51b
A diferencia de uniqid()
simple uniqid()
, esto produce salidas muy diferentes cada microsegundo. Además, no revela su cadena de "prefijo sal", ni que está utilizando 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 sobre uniqid()
simple uniqid()
.
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, necesitaría usar un generador de números aleatorios criptográficamente seguro. (1) Los UUID no están diseñados para ser criptográficamente seguros, solo garantizados ú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.
- 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 inferir el valor de la siguiente iteración, es decir, hay algún estado oculto en el generador que no se revela en el número y no puede inferirse examinando una secuencia de números del PRNG.
Si entra en la teoría de números, puede encontrar formas de adivinar el estado interno de algunos PRNG a partir de una secuencia de valores generados. Mersenne Twister es un ejemplo de tal 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.
La versión 3 de los 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.