utilizar usuario una son seguridad segura seguir resguardo reglas recomendaciones qué proteger politicas politica para medidas las fuertes debes cuentas cuales crear contraseñas contraseña php authentication

php - usuario - resguardo de contraseñas



Mejores prácticas de PHP para autenticación de usuario y seguridad de contraseñas (8)

¿Cuáles son las mejores bibliotecas / métodos actuales para autenticar usuarios sin el uso de un CMS o framework pesado?

Las respuestas deben incluir sugerencias para cualquier cosa que piense que se debe considerar el estándar para el nuevo desarrollo de PHP que involucra autenticación de usuario.


Aquí hay muchas respuestas excelentes, pero siento que vale la pena decir esto, ¡NO trates de reinventar la rueda en este caso! Es extremadamente fácil arruinar la autenticación de usuario en una amplia variedad de formas. A menos que realmente necesite una solución personalizada y tenga un conocimiento sólido de los esquemas de seguridad y las mejores prácticas, seguramente tendrá fallas de seguridad.

OpenID es genial, o si vas a hacer tu propio, al menos usa una biblioteca establecida y sigue la documentación.


Es importante separar la capa de seguridad de su aplicación del resto. Si no hay distancia entre la lógica de su aplicación y su sistema de comunicación, es libre de comunicarse inseguramente en un solo lugar y de forma segura en otro lugar. Tal vez cometerá un error y enviará una contraseña en una cookie no encriptada, o tal vez se olvide de verificar las credenciales del usuario para un paso. Sin una "forma correcta" de comunicarse con el usuario, seguramente cometerá un error.

Por ejemplo, digamos que así es como se verifica a los usuarios ahora:

user_cookie = getSecureCookie() if (user_cookie.password == session_user.password) { do_secure_thing() ... }

Si se descubre una vulnerabilidad en getSecureCookie (), y utiliza este código para verificar a los usuarios en toda la aplicación, es posible que no encuentre todas las instancias de getSecureCookie () que deben corregirse. Sin embargo, si separa su lógica de su seguridad:

if (userVerified()) { do_secure_thing() ... }

... podrá volver a proteger su aplicación rápida y fácilmente. Tómese una "forma correcta" de hacer la seguridad, y será mucho menos probable que cometa un grave error de seguridad.


La mejor autenticación es utilizar autenticación de múltiples factores, idealmente una versión sin token en todos los inicios de sesión sensibles a la seguridad.

Protegido con contraseña y más fácil de usar con alta confiabilidad y seguridad. Hay varios disponibles más allá de EMC / RSA. Prefiero el PINSafe de SwivelSecure.

Igor S


Yo uso OpenID .

Pero al igual que utilizo el openid-selector proyectos openid-selector Google para hacer el trabajo pesado.
Página de demostración here .

Las ventajas obvias (de OpenID) son.

  • No necesita ser un experto en seguridad.
  • Los usuarios confían en los grandes sitios con su información.
  • Puede solicitar cosas como (apodo, etc.) pero el usuario tiene que aceptar.
  • No necesita preocuparse por:
    • procesos de registro
    • contraseña perdida / olvidada

OpenID es un método para autenticar usuarios en función de sus cuentas existentes en servicios web comunes como Yahoo, Google y Flickr.

Los inicios de sesión en su sitio se basan en un inicio de sesión exitoso en el sitio remoto.

No necesita almacenar información sensible del usuario o usar SSL para proteger los inicios de sesión de los usuarios.

Una versión actual de PHP de la biblioteca se puede encontrar here .


PHPass es una biblioteca de hashing de contraseñas liviana y de costo variable que utiliza bcrypt.

El costo variable significa que luego puede aumentar el "costo" de contraseñas hash para aumentar la seguridad sin tener que invalidar sus contraseñas de usuario hash previamente.

El tamaño de campo utilizado para el almacenamiento de hash es constante incluso cuando aumenta el "costo" debido a que no aumenta el tamaño del hash, sino el número de iteraciones necesarias para producirlo.


Implementar la autenticación de usuario de forma segura sin depender de un marco (o una biblioteca de terceros, como OpenID) para hacerlo por usted no es una tarea trivial.

En una vista general de 10,000 pies, debes decidir:

  • ¿Tiene nombres de usuario, direcciones de correo electrónico o ID de usuario como selector principal?
  • ¿Cómo debe almacenar contraseñas? PROTIP: password_hash() o scrypt son el camino a seguir.
  • ¿Cómo se debe manejar las casillas de verificación "recordarme"? Hay muchas estrategias malas para esto en Internet. Trate a cada uno de ellos con escepticismo, ya que pueden introducir vulnerabilidades en su aplicación.
  • ¿Cómo debe manejar la aplicación los usuarios que olvidan su contraseña?

La información en esta respuesta es relevante y actualizada a partir del 9 de mayo de 2015 y podría quedar obsoleta al concluir la competencia de hash de contraseñas.

Selectores primarios

En general, los nombres de usuario y las direcciones de correo electrónico son mejores que los números de identificación.

No debería haber ningún requisito de seguridad para mantener los nombres de usuario en secreto, porque en la práctica se filtrarán cuando alguien intente registrarse de todos modos.

Puedes decidir si tratar o no las direcciones de correo electrónico como un secreto. A los usuarios generalmente les gusta no estar expuestos a los spammers, scammers y trolls.

Hashing de contraseña

Debe usar password_hash() y password_verify() menos que tenga suficiente experiencia con la escritura de bibliotecas de criptografía para ir más allá.

Más allá de Bcrypt

A veces los desarrolladores prefieren ser creativos (por ejemplo, agregar un "pimiento", que generalmente significa contraseñas hash o HMACing con una clave estática) e ir más allá de las implementaciones estándar. Nosotros mismos hemos hecho esto, pero de manera muy conservadora.

Para nuestros proyectos internos (que tienen un margen de seguridad mucho más alto que los blogs de la mayoría de las personas), escribimos un envoltorio alrededor de esta API llamado PasswordLock que primero hashes una contraseña con sha256 , luego base64 codifica la salida hash cruda, luego pasa este codificado en base64 hash to password_hash() y, finalmente, cifra el hash bcrypt con una biblioteca de cifrado implementada correctamente .

Para reiterar, en lugar de acribillar, encriptamos nuestros hash de contraseñas. Esto nos da más agilidad en caso de una fuga (podemos descifrar y luego volver a encriptar porque conocemos la clave). Además, podemos ejecutar nuestro servidor web y base de datos en hardware separado en el mismo centro de datos para mitigar el impacto de una vulnerabilidad de inyección SQL. (Para comenzar a descifrar hashes, necesita la clave AES. No puede obtenerla de la base de datos, incluso si escapa al sistema de archivos).

// Storage: $stored = /ParagonIE/PasswordLock/PasswordLock::hashAndEncrypt($password, $aesKey); // Verification: if (/ParagonIE/PasswordLock/PasswordLock::decryptAndVerify($password, $stored, $aesKey)) { // Authenticated! }

Almacenamiento de PasswordLock con PasswordLock :

  1. hash(''sha256'', $password, true);
  2. base64_encode($step1);
  3. password_hash($step2, PASSWORD_DEFAULT);
  4. Crypto::encrypt($step3, $secretKey);

Verificación de PasswordLock con PasswordLock :

  1. Crypto::decrypt($ciphertext, $secretKey);
  2. hash(''sha256'', $password, true);
  3. base64_encode($step2);
  4. password_verify($step3, $step1);

Otras lecturas


Ingresar usando HTTP AUTH

  1. Usando Apache: http://httpd.apache.org/docs/2.2/howto/auth.html
  2. También es posible con IIS y otros servidores web .

Una vez autenticado, para PHP , solo tiene que usar $_SERVER[''PHP_AUTH_USER''] para recuperar el nombre de usuario utilizado durante la autenticación.

Esta puede ser una solución más rápida y, a veces, más flexible que manejar la solución a nivel de scripting, siempre que se necesite información limitada sobre el usuario, ya que todo lo que está disponible para usted es el nombre de usuario utilizado para iniciar sesión.

Sin embargo, olvídate de integrar tu autenticación en un formulario HTML a menos que implementes un esquema HTTP AUTH completo desde tu lenguaje de scripts (como se describe a continuación).

Transmitir su propio HTTP AUTH dentro de su lenguaje de scripting

En realidad, puede ampliar HTTP Basic Auth emulando en su lenguaje de scripting. El único requisito para esto es que su lenguaje de scripting debe poder enviar encabezados HTTP al cliente HTTP. Una explicación detallada sobre cómo lograr esto usando PHP se puede encontrar aquí: ( ver más en PHP y HTTP AUTH ).

Puede expandir el artículo anterior usando un esquema de autenticación típico, un almacén de archivos, incluso sesiones de PHP o cookies (si la información no es necesaria para ser persistente), lo que le brinda mucha más flexibilidad al usar HTTP AUTH, pero aún conserva cierta simplicidad.

Desventajas de HTTP AUTH

  1. La principal desventaja de la autenticación HTTP son las complicaciones que puede tener el cierre de sesión. La forma principal de borrar la sesión del usuario es cerrar el navegador o pasar un encabezado con la Autenticación 403 Requerida. Desafortunadamente, esto significa que la ventana emergente HTTP AUTH regresa a la página y luego requiere que los usuarios vuelvan a iniciar sesión o presionen cancelar. Puede que esto no funcione bien si se tiene en cuenta la usabilidad, pero se puede solucionar con algunos resultados interesantes (es decir, utilizar una combinación de cookies y HTTP AUTH para almacenar el estado).

  2. Las ventanas emergentes HTTP AUTH, la sesión y el manejo del encabezado HTTP están determinados por la implementación del navegador del estándar. Esto significa que se quedará atrapado con esa implementación (incluidos los errores) sin la posibilidad de una solución alternativa (a diferencia de otras alternativas).

  3. La autenticación básica también significa que auth_user y la contraseña aparecen en los registros del servidor, y luego debe usar https para todo, ya que de lo contrario el nombre de usuario y la contraseña también pasan por la red en cada consulta en texto sin formato.