¿Hay algún problema al usar la función crypt () de PHP con un salt adicional?

1

¿Es seguro mi script de autenticación de PHP? Noté que los hashes comienzan con las dos primeras letras del nombre de usuario. ¿Podría haber una falla de seguridad usando crypt () de tal manera?

<?php

// Credentials :
// admin / P4ssW0rd
// j.doe / r0x0r

$cred = array(
    'admin' => 'adkFV/7Pa.Em.',
    'j.doe' => 'j.4AzOhv10e1M'
);

$salt = 'abcdefg';
$user = $_POST['login'];
$pass = $_POST['pass'];

if (isset($cred[$user]) && crypt($salt . $pass, $user) == $cred[$user]) {
    echo 'Access granted';
} else {
    echo 'Access denied';
}
    
pregunta user46381 11.05.2014 - 14:57
fuente

2 respuestas

4

Su script es atroz de varias maneras:

  • Como lo señaló @Corneliux, la función crypt () de PHP utiliza la antigua función crypt() basada en DES del mundo Unix (precisamente, lo que se usó en Unix hace 20 años). Utilizará solo las primeras 8 letras de la contraseña provista, ignorando el resto. En su caso, las primeras 7 letras son el contenido de su variable $salt , no de la contraseña. Esto significa, en la práctica, que a un usuario se le otorgará acceso de administrador siempre que lo que ingrese como contraseña comience con una 'P'.

  • Incluso si crypt() usó un hashing de contraseña decente función , todavía lo usarías mal. En la función crypt() de PHP, se supone que debe proporcionar la sal como segundo parámetro; no lo pegues con la contraseña; en este momento, utiliza el nombre de usuario como sal.

  • Su variable $salt no es una sal de todos modos. El punto de una sal es cambiar ; idealmente, cada instancia de hashing de contraseñas debería tener su propio valor de sal (es decir, una nueva sal para cada usuario y una nueva sal cada vez que un usuario cambia su contraseña también). Un valor de sal codificado, siempre igual para todos, es exactamente lo contrario de lo que se supone que es una sal.

  • Escribir las contraseñas simples de los usuarios en los comentarios es, digamos, imprudente.

Hazte un favor: usa un PHP suficientemente reciente (al menos 5.5.0) y llama a password_hash () . Esa llamada usará bcrypt , que es tan buena como la que realmente puede obtener. No juegues con las sales: solo deja que la función genere una sal aleatoria internamente; también almacenará la sal codificada en el valor hash resultante, lo cual está bien.

    
respondido por el Thomas Pornin 11.06.2014 - 14:53
fuente
0

Como lo indica la documentación de PHP, crypt () solo toma los primeros 8 caracteres de la cadena:

  

El crypt basado en DES estándar () devuelve el salt como los dos primeros caracteres de la salida. También solo utiliza los primeros ocho caracteres de str, por lo que las cadenas más largas que comienzan con los mismos ocho caracteres generarán el mismo resultado (cuando se usa la misma sal).

Entonces tu sal debilita toda la seguridad aquí. Si tiene menos de 8 caracteres, solo se necesitará la primera contraseña (8-len (sal)) de la contraseña del usuario para autenticarse. Si son 8 o más caracteres, es barra abierta.

    
respondido por el Corneliux 12.05.2014 - 09:09
fuente

Lea otras preguntas en las etiquetas