2011-01-08 13 views
6

Hace unos años pregunté aquí en stackoverflow sobre cómo hacer que el almacenamiento de contraseñas PHP sea seguro. El main answer sugiere utilizar el siguiente algoritmo hashing:PHP Almacenamiento de contraseñas con HMAC + nonce - ¿Es importante la aleatoriedad de nonce?

function hash_password($password, $nonce) { 
    global $site_key; 
    return hash_hmac('sha512', $password . $nonce, $site_key); 
} 

La respuesta sugiere el uso de un azar nonce . ¿Hay alguna ventaja en tener un nonce aleatorio sobre simples nonces únicos?

Por ejemplo, cada usuario puede tener su propia identificación que no cambia. Sin embargo, supongamos que los ID de usuario son secuenciales (creados con la función de incremento automático de MySQL) y, por lo tanto, no son aleatorios. ¿La identificación del usuario sería buena o la aleatoriedad es importante?

Ahora, cada usuario puede elegir un nombre de usuario. Cada usuario tiene su propio nombre de usuario que no cambia, y dos usuarios diferentes no pueden tener el mismo nombre de usuario. Los nombres de usuario aún no son aleatorios, pero tampoco son secuenciales. ¿Serán los nombres de usuario lo suficientemente buenos como para ser un nonce? ¿Sería mejor que usar la ID de usuario?

+0

Su nonce debería ser una sal. Una sal es aleatoria por definición. He escrito una respuesta larga acerca de la salazón aquí: http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190 – Jacco

Respuesta

2

esto es todo en el supuesto que un nonce es una sal ...

Si por el valor de uso único que quiere decir una sal entonces sí que requiere más tablas del arco iris que se harán. Por lo general, una vez que sal de más de 20 caracteres es suficiente, pero para condiciones de seguridad extremas, querrá una nueva sal aleatoria para cada contraseña.

También es una buena opción en un hash lento http://www.php.net/manual/en/function.hash.php#89574, sin sarcasmo. Pero me gusta madurez.

No vi la mitad inferior de su respuesta. Para elaborar: Nonces se utilizan para evitar el uso de tablas de arco iris. Si las identificaciones funcionarán depende simplemente de la longitud de las identificaciones. La aleatoriedad no es técnicamente importante, pero solo hace que se necesiten más tablas de arcoíris. Un ejemplo sería, digamos que usaste un carácter "a" como nonce y la contraseña tenía 2 caracteres de largo, una tabla de arco iris de a-aa, a-ab a-ac y así sucesivamente tendría que crearse. Si usa una aleatoria cada vez, quizás todas las permutaciones de 'a' tendrían que hacerse + todas las permutaciones de los otros caracteres aleatorios.

Pero en general, hacer tablas de arcoiris toma bastante tiempo. Entonces, si se te ocurre una sal, es probable que sea la tabla del arcoíris, ya que no existe.

+0

Esta respuesta es correcta, pero no tiene nada que ver con el pregunta. HMAC no es un hash sino un algoritmo MAC. También se llama key-hash. Por lo tanto, el nonce está en la pregunta no es el término correcto. Debe ser una clave (privada). Y en ese caso, una clave es segura (a menos que trabajes para o quieras proteger contra una agencia nacional). – Henri

+0

Así el nombre "NoviceCoding" ... Muchas gracias por la explicación. Intento compartir el poco conocimiento que tengo sobre estas cosas, pero, como esta vez, era irrelevante. Gracias de nuevo. – NoviceCoding

+0

Una sal * debe ser aleatoria *. Una identificación de usuario definitivamente no es adecuada para usarla como sal: hay muchos sistemas con una identificación de usuario 1. (incluso hay una gran probabilidad de que la cuenta de administrador se encuentre en los id. Bajos) Cualquier cosa predecible debilita el esquema. – Jacco

0

Para almacenar la contraseña suficiente para usar:

sha512(salt + password) 

salt debería ser aleatoria y única para cada usuario. La sal aleatoria hará imposible el ataque de tablas hash precalculadas: cada usuario requerirá sus propias tablas hash calculadas. Si usa sal no aleatoria, entonces existe la posibilidad de que la tabla precalculada exista será mayor.

posición sal antes contraseña ayudará a ocultar los patrones de hash en caso de que algunos usuarios tengan la misma contraseña.

Nonce no es necesario, porque es para prevenir un ataque de respuesta. Esta protección no es posible en su arquitectura.

Usando HMAC para evitar colisiones es inútil, porque a) se utiliza de hash no para MAC, b) para hacer probabilidad de colisión 50% durante aproximadamente 2^256 valores SHA-512 you need to calculate.Y 2^256 es un número verdaderamente astronómico.

+0

Este es un mal consejo. HMAC es el estándar indiscutible para el almacenamiento de contraseñas, ya que requiere una gran cantidad de recursos para la fuerza bruta. Use HMAC + SHA512 si desea usar SHA. – mattbasta

2

Descubrí que había un tutorial bastante bueno escrito en línea sobre este tema. No recuerdo bien en qué parte de google lo encontré, pero déjame ver si puedo descifrar la función lo suficientemente bien, ya que está justo en frente de mí ...

Primero la función, puede crear una clave longitud de cualquier tamaño. Me tomé la libertad de comentar que es bastante fuerte ...

function pbkdf2($password,$salt,$iter_count = 1500,$key_length = 32,$algorithm = 'sha512') 
{ 
    /* 
     @param string password -- password to be encrypted 
     @param string salt -- salt to encrypt with 
     @param int iter_count -- number of times to iterate blocks 
     @param key_length -- length of key to return 
     @param $algorithm -- algorithm to use in hashing 

     @return string key 
    */ 

    //determine the length of the hahs 
    $hash_length = strlen(hash($algorithm,NULL,TRUE)); 
    //determine the number of key blocks to compute 
    $key_blocks = ceil($key_length/$hash_length); 
    //initialize key 
    $key = ''; 

    //create the key itself 
    //create blocks 
    for($block_count = 1;$block_count <= $key_blocks;$block_count++) 
    { 
     //initalize hash for this block 
     $iterated_block = $block = hash_hmac($algorithm,$salt.pack('N',$block_count),$password,TRUE); 
     //iterate blocks 
     for($iterate = 1;$iterate <= $iter_count;$iterate++) 
     { 
      //xor each iterate 
      $iterated_block ^= ($block = hash_hmac($algorithm,$block,$password,TRUE)); 
     } 
     //append iterated block 
     $key .= $iterated_block; 
    } 
    //return the key 
    return substr($key,0,$key_length); 
} 
  1. primero que hace es averiguar la longitud de la matriz.
  2. A continuación se determina cuántos se requieren bloques clave para la longitud de la clave especificada
  3. A continuación se inicializa el hash (clave) para volver
  4. pone en marcha el bucle que va a crear cada bloque
  5. toma el hash inicial del bloque con el contador de bloques en binario anexa a la sal
  6. comienza el bucle para iterar los bloques $ veces iter_count (crear un hash de sí mismo)
  7. XOR cada iteración y añadirlo a $ iterated_block (xor de hash anterior a actual)
  8. bucle termina XOR
  9. append $ iterated_block a $ clave para cada bloque
  10. bucle bloque termina
  11. la tecla de retorno

Siento que esto es probablemente la mejor manera de hacer esto. Tal vez estoy demasiado paranoico?

Cuestiones relacionadas