2010-12-20 17 views
15

Estoy buscando consejos sobre cómo securely almacenar contraseñas en MySQL usando PHP.¿Cuáles son las mejores prácticas para encriptar contraseñas almacenadas en MySql utilizando PhP?

Pasando por alto las limitaciones de PHP en sí, quiero saber más sobre salazón, hash y encriptación de estos chicos malos.

Obviamente, las personas seguirán utilizando contraseñas débiles a menos que se les obligue a hacerlo de otra manera, pero es la forma en que las guardo lo que es importante para mí. Las contraseñas de mis usuarios son mucho más importantes para mí que la base de datos en sí misma y, por lo tanto, quiero mantenerlas de forma tal que sean minuciosas y monótonas para cualquier script kiddie que intente invertir. Obviamente, con la debida diligencia casi cualquier cosa puede ser derrotada, pero no me importaría hacer esto particularmente molesto.

Hay dos escenarios que estamos viendo.

  1. The kiddie tiene una copia completa de la base de datos.
  2. El niño tiene una copia completa del PHP utilizado para crear la contraseña y la base de datos.

Todos y cada uno de los consejos sobre este tema se aprecia graciosamente.

+1

La mejor manera es no utilizar contraseñas en absoluto. Ver InstaPaper. –

+0

¿Son sus usuarios locales o por Internet? –

+0

Tanto locales como de Internet. Prefiero no depender de los recursos de Internet, pero supongo que esto podría ser una opción (por ejemplo, agarrar la sal de un proveedor de terceros). – Matt

Respuesta

17

Use bcrypt. Si alguien tiene la tabla de usuarios de su base de datos, entonces pueden usar la fuerza bruta/tablas de arcoiris/etc al contenido de su corazón. Incluso con sal, si está usando MD5 o algún otro algoritmo de hash rápido (que no están diseñados para resolver este problema, por cierto); es solo una cuestión de tiempo antes de que pueda ser descifrado.

Cualquier algoritmo de hashing bien conocido y ampliamente respaldado va a tener este mismo "defecto" básico (si se puede llamar así, es realmente por definición). La diferencia es que bcrypt es lento como melaza al realizar la operación de hash, lo que hace que un ataque de fuerza bruta sea mucho menos efectivo.

Para una discusión absolutamente grande sobre los méritos de bcrypt, los peligros de otros enfoques, y la dificultad de la seguridad de contraseñas en general, lea this thread. Tiene muchos comentarios de mucha gente que saben mucho más sobre este tipo de cosas que yo, y es de esperar que te ayude a entender más sobre los problemas que están en juego.

+0

Sí, bcrypt tiene la ventaja de que puede hacer que el proceso de hash sea arbitrariamente lento. No es gran cosa en su servidor si lleva un cuarto de segundo codificar una contraseña.Pero le importa al niño si solo puede calcular cuatro hashes por segundo en lugar de miles. – eaj

+0

+1 para repetir el sitio web. –

+0

@ Time Machine Lol, pensé que lo sacaría mientras escribía el resto de mi respuesta :) – Donut

1

Si sus usuarios utilizan Internet, OpenId sería una de sus mejores opciones. http://openid.net/

Si sus usuarios están en su red, ¿puede hacer Seguridad integrada?

En otras palabras ... no almacene sus contraseñas.

+0

Pueden estar en Internet, y también pueden ser locales a veces. Debido a esto no puedo depender de OpenID. ¡Gracias! – Matt

1

Por lo general, "salados" contraseñas (como con bcrypt) significan que no la contraseña en sí está almacenado, pero sólo algo así como

salt 
    hash(salt with password appended) 

Ahora bien, si el infantil tiene su base de datos (y, por supuesto, el código - hay no tiene sentido mantener el código en secreto), él/ella solo puede adivinar las contraseñas, calcular el hash salado y comparar. Si la función hash es cara (como bcrypt es), entonces adivinar es costoso también.

1

Es muy sencillo

store(sha256("somesalt" + password)); 

Y nadie será capaz de darle la vuelta :)

Ver también: https://stackoverflow.com/questions/3897434/password-security-sha1-sha256-or-sha512

+0

Suponiendo que tengan la base de datos/php son conscientes de la sal. Brute forzar su paso más allá de esto es simplemente una cuestión de agregar la sal al frente de la contraseña. – Matt

+0

No evitará ataques de diccionario. –

+0

@MAtt: La sal debe ser conocida, de lo contrario las contraseñas no pueden ser v erificado. La fuerza bruta es teóricamente posible, pero no en la práctica. @Time Machine: ¿Cómo es eso? Para eso es la sal. Si es suficientemente largo y único, ningún diccionario lo tendrá. –

8

Suponiendo que está usando nombre de usuario y contraseña como tokens de autenticación que se pueden almacenar de forma segura lo siguiente para garantizar que los datos no puedan verse comprometidos.

  • nombre de usuario (en texto plano)
  • Sal (cadena aleatoria)
  • Salado Hash (sha1 (nombre de usuario + sal + contraseña))

Utilizando el esquema, un atacante no puede usar rainbow tables en su contra y las contraseñas no son recuperables por ningún medio (razonable). (Es decir, siempre que su atacante no sea el gobierno)

Aunque el atacante tiene los pares de sal y hash, no es posible usar tablas de arcoiris porque todos los hashes posibles deberán computarse de todos modos, usando el sal que se les ha dado, por lo que es un nuevo ataque de fuerza bruta para cada usuario.

Incluso con el código fuente y el atacante no podrá obtener las contraseñas porque la fuerza/seguridad está en el algoritmo hash, no en su código.

Combina esto con el uso de bcrypt según la respuesta de Donut y eres realmente bastante seguro. Es decir:

  • nombre de usuario (en texto plano)
  • Sal (cadena aleatoria)
  • Salado Hash (bcrypt (nombre de usuario + sal + contraseña))
+0

+1: con una advertencia. "por cualquier medio" ... no exactamente. Todavía puede construir tablas de arcoiris y encontrar colisiones. Sin embargo, necesitarías uno por cada sal. Lo cual, aunque es posible, simplemente no es factible (de ahí el +1). Si usted es la NSA o alguna otra agencia gubernamental, entonces todas las apuestas están apagadas. – NotMe

3

Tomando consejo de here, para mayor diversión también puede cambiar dinámicamente su sal. Por ejemplo, use sales diferentes para nombres de usuario de diferente duración, use la fecha de registro del usuario como sal. Esto hace que incluso si alguien llega a su base de datos, no pueden simplemente generar de nuevo el hash, tienen que calcular una tabla hash para cada sal que usted utilizó.

+0

Esta es una excelente adición al tema. Fue discutido en una clase de seguridad que tomé. En realidad, todo lo que necesita hacer es incrementar la sal en 1 cada vez que agrega un usuario. Siempre que la sal sea diferente para cada usuario, las tablas del arcoíris tendrían que volver a calcularse para cada usuario, haciendo que un ataque de fuerza bruta sea extremadamente molesto. +1 –

+1

todos los que consideren almacenar contraseñas en una base de datos deben leer esta publicación de blog – niteria

Cuestiones relacionadas