En tu código, tienes para completar $legal_characters
con la lista de caracteres que aceptas como parte de una contraseña. Por ejemplo:
$legal_characters = "abcdefghijklmnopqrstuvwxyz";
si quieres contraseñas que consistan en letras minúsculas (todas letras latinas en minúsculas, pero no otros caracteres ni acentos).
Este código es un poco raro; utiliza mt_rand()
(un PRNG interno) sembrado con la hora actual y el ID del proceso para obtener la longitud de la contraseña, entre 15 y 60 caracteres. Luego usa /dev/urandom
para la contraseña, que es inteligente ya que mt_rand()
no es criptográficamente segura (especialmente porque la ID del proceso no es algo secreto, y tampoco lo es la hora actual).
La generación de la contraseña real funciona así: produce 500 bytes aleatorios (desde /dev/urandom
), luego elimina todos aquellos que no están en el conjunto de caracteres aceptados (que es el " tr
"), y finalmente trunca de nuevo Secuencia de caracteres restante a la longitud deseada. Este proceso genera secuencias uniformemente aleatorias, por lo que es bueno, y /dev/urandom
es el PRNG apropiado para eso. Tenga en cuenta, sin embargo, algunas advertencias:
-
Si el conjunto de "caracteres legales" es pequeño, podría terminar con una contraseña más corta. P.ej. Si desea contraseñas con solo dígitos del 1 al 6, habrá, en promedio, solo 12 bytes iguales en los 500 bytes aleatorios. El código no tiene ningún seguro para "demasiado corto". Si establece $legal_characters
en todas las 26 letras minúsculas, entonces aproximadamente 1 byte en 10 será legal (los valores de bytes varían de 0 a 255, y 26/256 está cerca de 1/10) y, en promedio, el " tr
"parte producirá unos 50 caracteres, y es extremadamente improbable que produzca menos de 20. Sin embargo, vale la pena señalar que debería ser una prueba de fallos.
-
No tiene mucho sentido tener una longitud variable para la contraseña. Si una contraseña de longitud mínima es aceptable en términos de seguridad, entonces todas las contraseñas podrían tener esa longitud. Y si es no aceptable, ¿por qué usas esa longitud mínima? Es mejor que uses una sola longitud fija, en lugar de un rango. Esto le permitiría eliminar seed_random()
y mt_rand_custom()
, simplificando sustancialmente el código.
-
Una "contraseña" es algo que un ser humano podrá escribir y memorizar, por lo tanto, "palabra". ¿Memorizará una secuencia de 60 caracteres? Estoy seguro de que existe un nombre médico para tal condición.
-
Debe establecer la longitud de las contraseñas en un valor "apropiado" de tal manera que la entropía sea lo suficientemente alta. Si hay x caracteres legales y la longitud de la contraseña es n , entonces la entropía será xn . Lo que se necesita de la entropía depende del uso previsto. Para autenticar usuarios en un sitio web, a través de un túnel SSL apropiado, 2 40 ("40 bits" de entropía) es más que suficiente, lo que se traduce en 9 letras minúsculas (26 9 es mayor que 2 40 ).
-
El código usa unixismos ( /dev/urandom
, head
, tr
...) y tendrá dificultades para ejecutarse, por ejemplo, en un servidor Windows (y PHP también ejecuta Windows ).
Resumen: las contraseñas serán seguras, pero el código es extraño. Debe eliminar la longitud de la variable, y si sus usuarios pueden tragar contraseñas de 60 caracteres, felicítelos por mí. O venderlos a un zoológico. Aquí hay un código simplificado que debería estar bien (advertencia: no uso PHP, así que estoy improvisando aquí):
function generate_password() {
return shell_exec('head -c 500 /dev/urandom | tr -dc abcdefghijklmnopqrstuvwxyz | head -c 9; echo');
}