2011-01-26 35 views
11

Estoy buscando construir un sistema de inicio de sesión y después de leer el manual php cuando pasas una sal de 2 dígitos a la función crypt(), devuelve una cadena hash, y los primeros 2 dígitos de la cadena son la sal que usaste.¿Por qué PHP crypt() antepone la sal al hash?

ejemplo:

$salt = "kr"; 
echo crypt("mysecret",$salt); //returns "kreOI.F7eOQMY" 

Mi primer pensamiento fue, ¿no sería esto ayuda a alguien que está tratando de revertir el hachís?

Miré hacia arriba salt en la wikipedia que decía:

Para mayor seguridad, el valor de la sal se mantiene en secreto.

Así que no entiendo por qué la función cripta devolverá todos los valores hash precedidos con el valor de sal utilizado?

¿Hay alguna razón para esto? ¿Debería ser esto una preocupación de seguridad?

+0

Es por eso que recomiendo una sal de dos partes. Uno en un archivo de configuración que es secreto pero igual para todos los usuarios, y una parte guardada junto con la contraseña que es diferente para cada usuario/generada aleatoriamente. – CodesInChaos

+0

@meager, en realidad estoy tratando de actualizar uno que heredé. –

+3

Wikipedia no debe tomarse como un evangelio. Las sales no son secretas –

Respuesta

1

La función crypt() está obsoleta. Se usó para cifrar contraseñas para sistemas Unix de estilo antiguo, antes de que apareciera el soporte de contraseñas ocultas. La sal estaba allí para aumentar la complejidad de la fuerza bruta forzando la contraseña. Sin embargo, dado que la sal fue generada aleatoriamente por el subsistema de contraseñas, tenía que ser almacenada en forma clara para que cualquier acción de contraseñas futuras pudiera funcionar. Si la sal se hubiera incrustado en la contraseña antes de cifrar, no habría ninguna forma práctica de verificar una contraseña, tendrías que probar cada sal posible cada vez que se realizara una verificación de contraseña, lo cual es muy poco práctico. Por lo tanto, la sal se agregó a la contraseña cifrada, por lo que podría extraerla para usarla en el futuro.

crypted password: xxabcdefghijklmn 
        ^^- salt 
        ^^^^^^^^^^^^^^-- crypted pw 

if ('xx' + crypt('xx' + password) == 'crypted string') then 
    password is ok 
endif 

En estos días, crypt() es el equivalente de seguridad de un anillo decodificador de caja de cereal. Tiene fines históricos y almacenamiento de baja seguridad "a quién le importa si está agrietado". Para cualquier uso moderno de contraseñas, sería mejor usar hashes más modernos, como sha1/sha256/md5. E incluso md5 se considera roto en estos días, sha1 tiene grietas alrededor de los bordes, y (la última vez que revisé) sha256 sigue siendo seguro.

+0

Esto tiene sentido, por lo que si tuviera una base de datos llena de usuarios con contraseñas almacenadas. ¿Hay alguna forma de que los convierta a algo más como sha256, o debería "convertirlos" la próxima vez que el usuario inicie sesión? ya que obviamente tendría la contraseña sin procesar en ese momento. Gracias. –

+0

Si todo lo que tienes es la contraseña hash, entonces la contraseña original se ha ido, es por eso que es un hash. Una operación unidireccional desde texto sin formato-> hashtext. Convertir en autenticación con el antiguo hash es una forma de hacerlo, a menos que quiera invalidar la contraseña de todos, generar nuevos con el nuevo hash y forzarlos a "volver" a su antiguo PW y almacenarlo con el nuevo algoritmo hash. también. –

+6

La sal * no * está allí para aumentar la complejidad de la fuerza bruta. Está ahí para evitar el intercambio de tiempo y espacio de una mesa arcoiris. – erickson

3

Sí, se supone que la sal debe mantenerse en secreto, pero también lo es el hash de la contraseña. Es perfectamente aceptable que se los mantenga igualmente en secreto en el mismo lugar. Para verificar una contraseña contra el hash, debe combinar la sal con la contraseña y luego compararla con el hash. Por lo tanto, cualquier usuario o proceso con derecho a ver el hash de la contraseña también debería tener derecho a ver el sal, ya que el hash de la contraseña en sí mismo no es útil para verificar las contraseñas (a menos que sea bruta).

El propósito de la sal es que si dos usuarios diferentes tienen la misma contraseña, hagan hash a cosas diferentes. Esto también significa que los ataques de diccionario son mucho más complejos porque no puedes simplemente codificar todas las contraseñas probables y luego compararlas con una lista de hashes de contraseña de usuario para encontrar contraseñas de múltiples usuarios. En su lugar, debe probar las contraseñas de una sal individual para encontrar la contraseña de un usuario o probar todas las combinaciones de contraseñas probables con sales múltiples para encontrar coincidencias. Pero el conocimiento de la sal, por sí mismo, no significa que pueda revertir el hash de la contraseña. Simplemente significa que puedes hacer un ataque de diccionario al hash de contraseñas.

Si puede encontrar una manera de mantener la sal más segura que el valor hash, ciertamente no sería algo malo, pero es difícil ver cómo es factible cuando un programa que necesita acceso necesita acceso a ambos.

1

La sal se agrega al ha para que sepa qué sal usar cuando obtiene la contraseña y desea ver si coincide con el hash. La idea aquí es usar una sal diferente para cada contraseña para que alguien no pueda calcular previamente una tabla hash.

También podría adjuntar un segundo sal a cada contraseña (lo mismo para todos) y no decirle a nadie lo que es.

1

PHP crypt hereda este comportamiento de la función UNIX crypt(), que se utilizó para generar hash de contraseñas en el archivo UNIX passwd. Es necesario almacenar la sal en algún lugar, o no puede verificar más adelante que la contraseña es correcta. Para el archivo passwd, el comportamiento simple fue solo anteponer el valor sal (siempre dos caracteres) al inicio de la contraseña cifrada, lo que hace que sea sencillo almacenarlo en un solo campo.

La afirmación de que el valor de la sal debe mantenerse en secreto está sujeta a interpretaciones erróneas. Para obtener la mejor práctica, no debe publicar sus sales, de la misma manera que no debe publicar sus hashes de contraseña. Darle a un atacante los hash y sales hace que sea más fácil para ellos ejecutar un ataque de fuerza bruta sin generar tráfico sospechoso en su sistema. Sin embargo, el sistema aún debe estar seguro incluso si un atacante puede ver tanto la contraseña saliente como la hash.

De hecho, no hay ningún lugar donde puede almacenar el hash que, en principio, no podría ser comprometido por un hacker de la misma manera que las contraseñas hash. Si el código de verificación de contraseña puede acceder a él, debe suponer que alguien que haya comprometido el sistema también podría tener acceso a él.

28

El autor del artículo de Wikipedia está combinando sal con la idea de espacio de búsqueda, lo que implica que la sal es una forma de detener los ataques de fuerza bruta. La seguridad no se mejora al confundir estas ideas; alguien que no puede reconocer y delinear estas dos cuestiones no es una guía creíble.

El propósito de sal es frustrar las tablas de búsqueda pre calculadas (como una tabla Rainbow). Salt evita que un atacante intercambie "espacio" por "tiempo". Cada pedacito de sal duplica los requisitos de almacenamiento para una mesa; una sal de dos bytes hace una gran diferencia (65536 veces), pero ocho bytes requerirían dispositivos de almacenamiento "yottabyte" inexistentes para las tablas de búsqueda.

La sal debe almacenarse en algún lugar. Si tuvieras una forma efectiva de mantener un "secreto", ¿por qué no usarlo para almacenar la contraseña y olvidarte de hash por completo? No; si desea seguridad real, debe diseñar el sistema para estar a salvo de un ataque de fuerza bruta, aunque el atacante conozca la sal. La presunción del artículo de que la sal se puede mantener en secreto se debe tratar como falsa.

Los ataques de fuerza bruta se previenen mejor fortaleciendo las teclas (aplicando la función de hash miles de veces), y reglas de selección de contraseñas (una longitud mínima, dígitos, caracteres especiales).

Suponiendo que la sal no se puede mantener en secreto fomenta un mejor fortalecimiento de las claves y la selección de contraseñas, y esto lleva a un sistema más seguro.

+0

Vea una respuesta relacionada [aquí.] (Http://stackoverflow.com/questions/213380/the-necessity-of-hiding-the-salt-for-a-hash/215165#215165) – erickson

Cuestiones relacionadas