2010-08-20 11 views
6

Esta pregunta es sobre un problema de programación específico que estoy teniendo: quiero asegurarme de que mi código (y el algoritmo de software) sean suficientes para almacenar las credenciales de usuario en una base de datos.¿Mi algoritmo de seguridad de PHP almacena efectivamente las credenciales del usuario?

// Get a 32 character salt like '69Mt6nexL1rsjWnu011S53MpB/WmT4Vl' 
$passwordSalt = Security::generateBase64Salt(); 

$user = new User(); 
$user->setUsername($_POST['username']); 

// $_POST['password'] comes in as a 128 character string 
// Client side javascript is used to sha512 the string before sending it over POST 
// see http://pajhome.org.uk/crypt/md5/ 
// This prevents novice eavesdroppers from capturing the raw password in plaintext 
$user->setPassword(
    hash('sha512', $passwordSalt.$_POST['password']) 
); 
$user->setPasswordSalt($passwordSalt); 
$user->save(); 

Aquí está la entrada de la base de datos para una determinada contraseña:

alt text

Contraseña:

69a78a7586a111b8a567b2d4f42f93f01fb59d337f7fa3c35949a66b246095778c1fa01ff4026abace476091e1e9a183bbdec1c31b12ce3f786921895c98cf6f

Sal:

69Mt6nexL1rsjWnu011S53MpB/WmT4Vl

Preguntas:

  • ¿Hay alguna heredar defectos con este algoritmo?
  • ¿Está bien almacenar la sal en la misma base de datos y tabla que el hash salt + password?
  • ¿Tener una contraseña grande de 128 caracteres provocará problemas de rendimiento de inicio de sesión (en una magnitud de varios segundos) si tengo varios cientos de miles de usuarios en la tabla?
  • ¿Se pueden revertir estos datos para producir la contraseña original?

para la diversión:

voy a PayPal $ 5 si me puede proporcionar la contraseña original utilizando la sal y la sal + hash de la contraseña.

+0

¿Qué sentido tiene utilizar una sal si la envía en texto sin cifrar y anteponiendo su contraseña con ella? Yo mezclaría la contraseña con la sal al menos. – Jeroen

+0

Tu doble hashing la contraseña ¿verdad? Una vez que el cliente (sin sal), luego otra vez en el lado del servidor (con sal)? –

+0

Correcto. Gracias por tu increíble respuesta a continuación también. =] –

Respuesta

5

¿Hay algún error heredado con este algoritmo?

No está abierto a los ataques de arco iris (debido a la sal aleatoria). Sha512 es un algoritmo bastante nuevo, pero actualmente no tiene colisiones conocidas, por lo que es bastante seguro. La forma en que tus contraseñas de almacenamiento se hace bien. El proceso de verificación también es importante (limita la velocidad de los ataques de fuerza bruta) y bloquea los servidores de ataques desde otros ángulos que podrían intentar acceder a la base de datos. Si un atacante podía obtener acceso a la base de datos, probablemente podría extraer contraseñas simples con bastante rapidez, pero cualquier contraseña compleja probablemente sería más allá de un simple ataque de fuerza bruta (incluso si tuviera acceso directo a los valores hash).

¿Está bien almacenar la sal en la misma base de datos y tabla que el hash salt + password?

Tienes que almacenarlas si quieres poder validar las contraseñas (supongo que quieres). La razón principal para salar una contraseña es eliminar la posibilidad de un ataque de arco iris. A menudo, estos datos incluso se almacenan en la misma columna que la contraseña hash utilizando un símbolo para separarlos.

¿Tener una contraseña grande de 128 caracteres causará problemas de inicio de sesión (en una magnitud de varios segundos) si tengo varios cientos de miles de usuarios en la tabla?

Punto de referencia cuánto tiempo (en segundos) se tarda en verificar una contraseña (hash('sha512', $salt.$password_attempt)). Encuentre el inverso de ese número, y eso probablemente sea similar a la cantidad de intentos de contraseña que puede manejar por segundo por núcleo de CPU.

¿Se pueden revertir estos datos para producir la contraseña original?

Sí, pero tomaría un montón de esfuerzo, ya que al usar una sal aleatoria, las tablas de arcoiris ya no funcionarán, y sha512 requiere una buena cantidad de CPU para ejecutarse y no tiene colisiones conocidas. Si la contraseña era bastante simple, podría adivinarse. Si le preocupa invertir los valores hash, puede ser una buena idea poner un límite bajo en la complejidad de la contraseña (verificándola en un diccionario, ¿contiene los símbolos superior/inferior/números/símbolos)?

+0

¿Por qué votar abajo? –

6

Todo Kendall dijo, y ..

.. Saltar el hash que se realiza en el lado del cliente JavaScript. En su lugar, solo compre un certificado SSL y publique las credenciales en https. Te protegerá de espías novatos y atacantes experimentados.

Y además, una vez que hash en el lado del cliente, efectivamente se convierte en tu contraseña. Si un espía intercepta la contraseña hash, puede pasarla a su servidor y todo funcionará.

+0

Una razón para hackear en el lado del cliente es eliminar la posibilidad de que la contraseña sea interceptada (para aquellos usuarios que usan la misma contraseña). Hay formas de atacar MITM SSL, por lo que no es 100% infalible. Dicho todo esto, creo que tiene razón en su llamado para omitir ese paso, ya que esa es una parte tan pequeña del problema. –

+1

Las contraseñas hash del lado del cliente no resolverán los ataques MITM, porque la contraseña hash * se convierte en * la contraseña. SSL no es 100% infalible, pero a esa escala el encriptado en JS es quizás un 25% infalible. –

+0

No dije que resolvería el problema. Simplemente elimina parte de la utilidad del ataque MITM. Dado que al preconfigurar la contraseña, solo es útil en un sitio, en lugar de en la cuenta del otro usuario (porque muchos usuarios usan la misma contraseña una y otra vez). –

Cuestiones relacionadas