Quiero crear un token de generador que genera tokens que no puede ser adivinado por el usuario y que están siendo único (para ser utilizado para el restablecimiento de contraseñas y códigos de confirmación).

A menudo veo que este código; ¿tiene sentido?

md5(uniqid(rand(), true));

De acuerdo a un comentario uniqid($prefix, $moreEntopy = true) rendimientos

primeros 8 caracteres hex = Unixtime, el pasado 5 de hex chars = microsegundos.

No sé cómo la $prefix-parámetro que se maneja..

Así que si usted no establece los $moreEntopy bandera de la verdad, da un resultado predecible.


PREGUNTA: Pero si usamos uniqid con $moreEntopy, ¿qué hash con md5 comprar con nosotros? Es mejor que:

md5(mt_rand())

edit1: voy a la tienda de este símbolo en una columna de base de datos con un índice único, así que voy a detectar columnas. Podría ser de interés/

InformationsquelleAutor Exception e | 2010-04-07

8 Comentarios

  1. 43

    rand() es un peligro para la seguridad y nunca debe ser usado para generar un token de seguridad: rand() vs mt_rand() (Mira la «estática» como imágenes). Pero ninguno de estos métodos de generación de números aleatorios es criptográficamente seguro. Para generar segura secerts una aplicación necesita acceso a un CSPRNG proporcionado por la plataforma, sistema operativo o el hardware del módulo.

    En una aplicación web es una buena fuente para asegurar secretos es no-bloqueo de acceso a una piscina de entropía como /dev/urandom. A partir de PHP 5.3, PHP aplicaciones pueden utilizar openssl_random_pseudo_bytes(), y la biblioteca Openssl van a elegir la mejor de entropía de la fuente basado en el sistema operativo, en Linux esto significa que la aplicación va a utilizar /dev/urandom. Este código snip de Scott es bastante bueno:

    function crypto_rand_secure($min, $max) {
            $range = $max - $min;
            if ($range < 0) return $min; //not so random...
            $log = log($range, 2);
            $bytes = (int) ($log / 8) + 1; //length in bytes
            $bits = (int) $log + 1; //length in bits
            $filter = (int) (1 << $bits) - 1; //set all lower bits to 1
            do {
                $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
                $rnd = $rnd & $filter; //discard irrelevant bits
            } while ($rnd >= $range);
            return $min + $rnd;
    }
    
    function getToken($length=32){
        $token = "";
        $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
        $codeAlphabet.= "0123456789";
        for($i=0;$i<$length;$i++){
            $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
        }
        return $token;
    }
    • md5() in this case is being used to obscure the time that it was created which is a legitimate use Que suena como la respuesta.
    • tengo un servidor de proceso que necesita para tomar los datos del formulario y guardar como uniquetoken.xml. Ya tengo el formulario listo para crear el archivo xml. Tan lejos estoy de nomenclatura de ellos con cada uno de los mmddyy.xml. ¿Cómo puedo reemplazar con md5(uniqid(mt_rand(), true)); ?
    • Este es inseguro. Ver Scott respuesta.
    • es, por lejos, la mejor fuente de entropía para una aplicación web.»
    • Estoy hablando sobre el fragmento de código que usted haya proporcionado y etiquetados como «para la mayoría de los fines de la seguridad esta es una buena señal», listo para ser utilizado por los noobs. Además, /dev/urandom no es «la mejor fuente de entropía», ya que es de no bloqueo. Hay una razón por la openssl_random_pseudo_bytes() existe.
    • openssl hará uso de /dev/urandom en un *nix cuadro buscar en él. Mediante una operación de bloqueo en una webapp es «noob».
    • fijo?

  2. 21

    Esta es una copia de otra pregunta he encontrado que se le pidió un par de meses antes de esto. Aquí hay un enlace a la pregunta y mi respuesta: https://stackoverflow.com/a/13733588/1698153.

    No estoy de acuerdo con el aceptado respuesta. De acuerdo a PHPs propio sitio web "[uniqid] does not generate cryptographically secure tokens, in fact without being passed any additional parameters the return value is little different from microtime(). If you need to generate cryptographically secure tokens use openssl_random_pseudo_bytes()."

    No creo que la respuesta podría ser más claro que esto, uniqid no es seguro.

    • Esto debe ser aceptado respuesta.
    • upvoted por lo que la gente realmente debería obtener el enlace en lugar de la aceptación de la respuesta.
    • Scott, yo no era consciente de que la vieja pregunta, sry. Supongo que openssl_random_pseudo_bytes() (PHP 5 >= php 5.3) no siempre disponibles en el momento de preguntar. Tienes razón, la aceptó respuesta ha sido cambiado y se refiere a su respuesta en este momento, para que otras personas no sean erróneos.
  3. 5

    Sé que el tema es viejo, pero aparece en Google, así que…

    Como otros dijeron, rand(), mt_rand() o uniqid() no le garantiza la unicidad… incluso openssl_random_pseudo_bytes() no debe ser utilizado, ya que utiliza características obsoletas de OpenSSL.

    Lo que usted debe utilizar para generar al azar hash (mismo como md5) es random_bytes() (introducido en PHP7). Para generar el hash con la misma longitud como MD5:

    bin2hex(random_bytes(16));

    Si está usando PHP 5.x se puede obtener esta función mediante la inclusión de random_compat biblioteca.

  4. 1

    Definir «único». Si te refieres a que dos tokens no pueden tener el mismo valor, entonces hash no es suficiente – debe ser respaldado con una singularidad de la prueba. El hecho de que proporciona el algoritmo de hash con entradas únicas no garantiza únicas salidas.

    • unique = no tiene el mismo valor de verdad. Cada símbolo está asociado con una dirección de correo electrónico única. Tal vez podríamos usar esto para hacer un token aleatorio único. Todavía estoy seguro de cuál es la mejor manera de hacer esto.
  5. 1

    Para responder a su pregunta, el problema es que usted no puede tener un generador que está garantizado aleatorio y único como al azar por sí mismo, es decir, md5(mt_rand()) puede llevar a los duplicados. Lo que quiere es «al azar que aparecen» valores únicos. uniqid da la id única, rand() afijos un número aleatorio por lo que es aún más difícil de adivinar, md5 máscaras el resultado a hacer que sea aún más difícil de adivinar. Nada es imposible de adivinar. Sólo tenemos que hacer es tan fuerte que ni siquiera quieren probar.

    • Usted dice «md5 máscaras el resultado a hacer que sea aún más difícil de imaginar». Así uniqueid genera un poco al azar el resultado es único. ¿Qué significa precisamente por enmascaramiento? Si me gustaría seguir este pensamiento que md5(md5(uniqid(rand(), true) significaría más de enmascaramiento, pero es peor a la derecha?
    • e, un doble md5() hash no mejora la secuirty de este sistema.
  6. 1

    Me encontré con una idea interesante, hace un par de años.

    Almacenar dos valores hash en la datebase, uno generado con md5($a) y el otro con sha($a). Luego chek si ambos valores son corecta. El punto es, si el atacante rompió su md5(), él no puede romper su md5 Y sha en el futuro cercano.

    El problema es: ¿cómo puede ese es el concepto que se utiliza con el token de generación necesaria para su problema?

    • No sólo la combinación de ellos con una cadena de pegamento como _ o – ser suficiente para crear una fusión de token que sería mucho más improbable que tenga una colusión ? Usted no necesita para mantenerlos en su base de datos independiente de los campos. Usted puede mantener como combinados. Y si usted necesita para hacer todas las operaciones que en ellos, usted puede apenas proceso de la cadena con una función. De esta manera el combinado de la cadena puede ser utilizado como un token para cualquier cadena única que requiere el proceso, como claves de sesión o de solicitudes de restablecimiento de contraseñas o muchas otras cosas.
  7. 0

    Primer lugar, el alcance de este tipo de procedimiento es crear una clave/hash/código, que será único para una determinada base de datos. Es imposible crear algo único para todo el mundo en un momento dado.
    Dicho esto, usted debe crear una llanura, una cadena visible, utilizando una costumbre alfabeto, y de comprobar que el código creado en contra de su base de datos (tabla).
    Si esa cadena es único, luego de aplicar un md5() a ella y que no puede ser adivinado por cualquier persona o cualquier secuencia de comandos.
    Yo sé que si usted cava profundamente en la teoría de la generación de cifrado usted puede encontrar un montón de explicación acerca de este tipo de generación de código, pero al ponerlo a real de uso es realmente no es tan complicado.

    Este es el código que uso para generar un sencillo de 10 dígitos de código único.

    $alphabet = "[email protected]#dD5%eE6^fF7&gG8*hH9(iI0)jJ4-kK=+lL[mM]nN{oO}pP\qQ/rR,sS.tT?uUvV>xX~yY|zZ`wW$";
    $code = '';
    $alplhaLenght = strlen($alphabet )-1;
    for ($i = 1; $i <= 10; $i++) {
        $n = rand(1, $alplhaLenght );
        $code .= $alphabet [$n];
    }

    Y aquí están algunas genera códigos, aunque puede ejecutar a ti mismo para ver que funcione:

    SpQ0T0tyO%

    Uwn[MU][.

    D|[ROt+Cd [email protected]

    O6I|w38TRe

    Por supuesto, puede haber un montón de «mejoras» que puede ser aplicado a ella, para hacerla más «complicado», pero si se aplica una md5() a esto, va a convertirse en, digamos que es imposible de adivinar» . 🙂

  8. -1

    MD5 es un buen algoritmo para la producción de de datos dependiente de la IDs. Pero en caso de tener más de un elemento que tiene el mismo flujo de bits (contenido), se va a producir dos similares MD5 «id».

    Así que si usted se acaba de aplicar a un rand() función, que es la garantía de que no crear el mismo número dos veces, no son muy seguros.

    Pero para una mayor distribución de las llaves, yo personalmente uso SHA1 o SHAx, etc… pero todavía tiene el problema de datos similares conduce a teclas similares.

    • Viejo post, pero ¿cómo se rand() garantía de que no se cree el mismo número dos veces?

Dejar respuesta

Please enter your comment!
Please enter your name here