php crypt - trailing dollar sign - extrae solo la parte de sal del hash - rellenando la sal

2

Estoy leyendo sobre función crypt () de PHP. Tengo algunas preguntas al respecto -

  1. ¿Cuál es el significado del signo '$' al final de la cadena de sal que veo en la mayoría de los ejemplos? El manual no dice específicamente nada acerca de terminar la cadena de sal con él.

  2. ¿Hay alguna forma de poder extraer solo la porción de sal del hash? Sé que probablemente no sea necesario, ya que la función crypt () lo hará internamente cuando haga una comparación. Pero solo por el gusto de hacerlo. Sólo para que yo vea la sal. Para egs considere este código

    $pass = 'secret'; $salt = '$2y$07$usesomesillystringforsalt$'; echo crypt($pass, $salt);

    El resultado de esto es $2y$07$usesomesillystringforex.u2VJUMLRWaJNuw0Hu2FvCEimdeYVO y no estoy seguro del límite entre la sal y el hash. ¿La 'e' en la sub cadena 'forex' es parte de la sal o el hash? Sería mucho más fácil si pudiera extraer la parte de sal.

  3. También el manual crypt () dice

      

    ... Blowfish hashing con una sal de la siguiente manera: "$ 2a $", "$ 2x $" o "$ 2y $", un parámetro de costo de dos dígitos, "$" y 22 caracteres del alfabeto ". / 0-9A-Za-z "....

    Según esto, espero 22 caracteres después del signo $ después del parámetro de costo. Pero considera este código

    $pass = 'secret'; $salt = '$2y$07$somesillystring$'; echo crypt($pass, $salt);

    La salida de esto es $2y$07$somesillystring$$$$$$.O6JLPmGlDvy4BicGmkuBD.DN8OYiIoG . Mi pregunta es por qué se rellena solo hasta 21 caracteres después del signo $ después del parámetro de costo. Esperaba que se rellenara hasta 22 caracteres.

pregunta user1720897 12.03.2014 - 09:26
fuente

1 respuesta

3

Los 22 caracteres que requiere son en realidad datos binarios codificados que se utilizan para la sal. Bcrypt / Blowfish / $ 2y $ solo usa los primeros 128 bits de sus 132 bits, por lo que los últimos cuatro bits se ignoran totalmente y no deben ser un signo de dólar porque no es un carácter válido para la codificación base64 modificada que se usa para el sal. Lo que sucedió es que especificó una sal demasiado corta, por lo que se rellenó con $ para que el sistema sepa que la sal ha terminado. La razón por la que termina siendo un . se debe a que, como solo se utilizan los primeros cuatro bits, los cuatro últimos se rellenan con ceros antes del comienzo del hash codificado. Un . es todos los ceros en esta codificación de tipo base64 y debido a que no hay un valor previo que afecte a los primeros cuatro bits del carácter 22, usted termina con solo el . . Además, me pregunto por qué eligieron usar dólares en lugar de . para representar la sal faltante, tal vez solo para diferenciar entre pedir ceros en la sal y la decisión automática de rellenar con ellos .

$pass = 'secret';
echo crypt($pass, '$2y$07$notlongenough'), "\n";
echo crypt($pass, '$2y$07$longenoughsortof......');

> $2y$07$notlongenough$$$$$$$$.uYiNG9WczQSWgnuPdcNj0jugGbSnaAC
> $2y$07$longenoughsortof......9dPQFbAgDCQ4RWEcZ4/ficmGapMNSpC

Solo tiene sentido proporcionar uno de los siguientes: . , O , e o u para el último carácter de la sal porque estos son los únicos caracteres en el conjunto de codificación que realmente afectan al primer cuatro bits Para su información, el rango completo es [./A-Za-z0-9] en ese orden, así que si los numera entre 0 y 63 y observa la expresión binaria de esos números, verá de dónde provienen esos cuatro caracteres.

Los ejemplos parecen usar erróneamente dólares finales. No son necesarios y, de hecho, no deberían estar presentes. Todo lo que necesita hacer es proporcionar suficientes bits para la sal en función del algoritmo que esté utilizando. Cada personaje debe ser lo más aleatorio posible hasta que se hayan proporcionado suficientes bits (es decir, un mínimo de 22 caracteres para Blowfish / $ 2y $).

La salida es entonces una concatenación de: algo-description, sal utilizada y resultado / contraseña con hash. El algoritmo conoce los límites binarios de dónde termina la sal y comienza la cadena de hash. No debe haber signos de dólar con $ 2y $ porque debería haber proporcionado una cadena de sal suficientemente larga que no constará de ningún signo de dólar (nuevamente, porque no está en el rango de caracteres válido para la codificación base64 modificada utilizada). / p>

Esto debería ser suficiente información para que extraigas la sal si así lo deseas. Pero PHP realmente recomienda el uso de password_hash , como hago si tiene v > = 5.5.0 enlace .

Esto generará automáticamente una sal aleatoria segura para usted usando /dev/urandom o CryptGenRandom() en Windows, ambos bien evaluados para ser suficientes para este propósito. Si ya has comenzado a usar crypt , password_hash es compatible, por lo que no tengas miedo de actualizarlo para usarlo.

    
respondido por el deed02392 12.03.2014 - 10:28
fuente

Lea otras preguntas en las etiquetas