¿Cuánto más seguro es esto que el MD5 simple ? Acabo de comenzar a buscar seguridad de contraseña. Soy bastante nuevo en PHP.
$salt = 'csdnfgksdgojnmfnb';
$password = md5($salt.$_POST['password']);
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '$password'");
if (mysql_num_rows($result) < 1) {
/* Access denied */
echo "The username or password you entered is incorrect.";
}
else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
#header("Location: ./");
echo "Hello $_SESSION[id]!";
}
Respuestas:
La forma más fácil de asegurar su esquema de almacenamiento de contraseña es mediante el uso de una biblioteca estándar .
Debido a que la seguridad tiende a ser mucho más complicada y con más posibilidades invisibles de arruinar que la mayoría de los programadores podrían enfrentar solos, usar una biblioteca estándar es casi siempre la opción más fácil y segura (si no la única) disponible.
La nueva API de contraseña PHP (5.5.0+)
Si está utilizando PHP versión 5.5.0 o posterior, puede utilizar la nueva API simplificada de hashing de contraseñas
Ejemplo de código usando la API de contraseña de PHP:
(En caso de que todavía esté utilizando el legado 5.3.7 o posterior, puede instalar ircmaxell / password_compat para tener acceso a las funciones integradas)
Mejora en hash salados: agregue pimienta
Si desea seguridad adicional, la gente de seguridad ahora (2017) recomienda agregar un ' pimiento ' a los hashes de contraseña (automáticamente) salados.
Hay una caída simple en la clase que implementa de manera segura este patrón, recomiendo: Netsilik / PepperedPasswords ( github ).
Viene con una licencia MIT, por lo que puede usarla como quiera, incluso en proyectos propietarios.
Ejemplo de código usando
Netsilik/PepperedPasswords
:La biblioteca estándar ANTIGUA
Eche un vistazo a: Marco de hash de contraseña PHP portátil : phpass y asegúrese de usar el
CRYPT_BLOWFISH
algoritmo si es posible.Ejemplo de código usando phpass (v0.2):
PHPass se ha implementado en algunos proyectos bastante conocidos:
Lo bueno es que no necesita preocuparse por los detalles, esos detalles han sido programados por personas con experiencia y revisados por muchas personas en Internet.
Para obtener más información sobre los esquemas de almacenamiento de contraseñas, lea la publicación del blog de Jeff : Probablemente esté almacenando contraseñas incorrectamente
Hagas lo que hagas si eliges el enfoque ' Lo haré yo mismo, gracias ', no lo uses
MD5
niSHA1
más . Son buenos algoritmos de hash, pero se consideran rotos por motivos de seguridad .Actualmente, usar crypt , con CRYPT_BLOWFISH es la mejor práctica.
CRYPT_BLOWFISH en PHP es una implementación del hash Bcrypt. Bcrypt se basa en el cifrado de bloques Blowfish, haciendo uso de su costosa configuración de teclas para ralentizar el algoritmo.
fuente
Sus usuarios estarán mucho más seguros si utiliza consultas parametrizadas en lugar de concatenar sentencias SQL. Y la sal debe ser única para cada usuario y debe almacenarse junto con el hash de contraseña.
fuente
Una mejor manera sería que cada usuario tenga una sal única.
El beneficio de tener sal es que dificulta que un atacante genere previamente la firma MD5 de cada palabra del diccionario. Pero si un atacante se entera de que tiene una sal fija, podría generar previamente la firma MD5 de cada palabra del diccionario con el prefijo de su sal fija.
Una mejor manera es que cada vez que un usuario cambia su contraseña, su sistema genera una sal aleatoria y la almacena junto con el registro del usuario. Es un poco más costoso verificar la contraseña (ya que necesita buscar la sal antes de poder generar la firma MD5) pero hace que sea mucho más difícil para un atacante pregenerar MD5.
fuente
crypt()
función). Y dado que debe recuperar el hash de contraseña de todos modos, el uso de una sal específica del usuario no hará que el procedimiento sea más costoso. (¿O quiso decir que generar una nueva sal aleatoria es costoso? Realmente no lo creo). De lo contrario, +1.Con PHP 5.5 (lo que describo está disponible incluso para versiones anteriores, ver más abajo) a la vuelta de la esquina, me gustaría sugerir que use su nueva solución incorporada:
password_hash()
ypassword_verify()
. Proporciona varias opciones para lograr el nivel de seguridad de contraseña que necesita (por ejemplo, especificando un parámetro de "costo" a través de la$options
matriz)volverá
Como puede ver, la cadena contiene la sal, así como el costo que se especificó en las opciones. También contiene el algoritmo utilizado.
Por lo tanto, al verificar la contraseña (por ejemplo, cuando el usuario inicia sesión), al usar la
password_verify()
función complementaria , extraerá los parámetros criptográficos necesarios del hash de la contraseña.Cuando no se especifica una sal, el hash de contraseña generado será diferente en cada llamada
password_hash()
porque la sal se genera aleatoriamente. Por lo tanto, la comparación de un hash anterior con uno recién generado fallará, incluso para una contraseña correcta.Verificación funciona así:
Espero que proporcionar estas funciones integradas pronto proporcione una mejor seguridad de contraseña en caso de robo de datos, ya que reduce la cantidad de pensamiento que el programador tiene que poner en una implementación adecuada.
Hay una pequeña biblioteca (un archivo PHP) que le dará PHP 5.5
password_hash
en PHP 5.3.7+: https://github.com/ircmaxell/password_compatfuente
password_hash()
ypassword_verify
no importa qué contraseña (correcta o no) usé, termino con la contraseña correctaEso está bien para mí. El Sr. Atwood escribió sobre la fuerza de MD5 contra las tablas del arco iris , y básicamente con una sal larga como esa estás sentado bonito (aunque algunos signos de puntuación / números aleatorios, podrían mejorarlo).
También puedes mirar SHA-1, que parece ser cada vez más popular en estos días.
fuente
Quiero agregar:
Por compatibilidad con sistemas antiguos, a menudo se establece un límite para la longitud máxima de la contraseña. Esta es una mala política de seguridad: si establece una restricción, configúrela solo para la longitud mínima de las contraseñas.
Para recuperar una contraseña olvidada, debe enviar la dirección por la cual el usuario puede cambiar la contraseña.
El hash de contraseña puede estar desactualizado (los parámetros del algoritmo pueden actualizarse). Al usar la función
password_needs_rehash()
, puede verificarlo.fuente