2010-08-24 11 views
36

He utilizado md5/sha1 sin sal durante mucho tiempo, pero como este método no es realmente seguro (y se está volviendo incluso menos seguro con el paso del tiempo) decidí cambiar a un sha512 salado. Además, quiero ralentizar la generación de hash down mediante el uso de muchas iteraciones (por ejemplo, 100).Muchas iteraciones de hash: agregue sal cada vez?

Mi pregunta es si debo añadir la sal en cada iteración o solo una vez al principio. Estos son los dos códigos posibles:

Anexar cada vez que:

// some nice big salt 
$salt = hash($algorithm, $salt); 

// apply $algorithm $runs times for slowdown 
while ($runs--) { 
    $string = hash($algorithm, $string . $salt, $raw); 
} 

return $string; 

Anexar una vez:

// add some nice big salt 
$string .= hash($algorithm, $salt); 

// apply $algorithm $runs times for slowdown 
while ($runs--) { 
    $string = hash($algorithm, $string, $raw); 
} 

return $string; 

primera vez que quería utilizar la segunda versión (se añade una vez) pero luego encontré algunos scripts que añaden sal cada vez.

Por lo tanto, me pregunto si si se agrega cada vez se agrega algo de fuerza al hash. Por ejemplo, ¿sería posible que un atacante encontrara alguna manera inteligente de crear una función 100timesSha512 que fuera mucho más rápida que simplemente ejecutar sha512 100 veces?

Respuesta

50

En resumen: Sí. Vaya con el primer ejemplo ... La función hash puede perder entropía si retroalimenta a sí mismo sin agregar los datos originales (parece que no puedo encontrar una referencia ahora, seguiré buscando).

Y para el registro, estoy a favor de hash varias veces.

Un hash que tarda 500 ms en generar no es demasiado lento para su servidor (teniendo en cuenta que la mayoría de las solicitudes no se realizan normalmente). Sin embargo, un hash que lleve tanto tiempo aumentará significativamente el tiempo que tardará en generar una tabla arcoiris ...

Sí, expone una vulnerabilidad de DOS, pero también previene los ataques de fuerza bruta (o al menos los hace prohibitivos) lento). No es absolutamente una solución de compromiso, pero a algunos de los beneficios superan los riesgos ...

Una referencia (más como una visión general) a todo el proceso: Key Strengthening

En cuanto a las colisiones en degeneración, la única fuente que pude encontrar hasta ahora es this discussion ...

Y poco más discusión sobre el tema:

  1. HEKS Proposal
  2. SecurityFocus blog on hashing
  3. A paper on Oracle's Password Hashing Algorithms

Y unos cuantos más enlaces:

  1. PBKDF2 on WikiPedia
  2. PBKDF2 Standard
  3. A email thread that's applicable
  4. Just Hashing Is Far From Enough Blog Post

hay un montón de resultados. Si quieres más, Google hash stretching ... Hay toneladas de buena información por ahí ...

+0

+1 No entiendo por qué esto tiene un voto negativo. Realmente apreciaría si pudieras encontrar esa referencia;) – NikiC

+0

+1 por la vulnerabilidad DoS. Aún creo que estás recomendando un error. – rook

+1

@ The Rook: Considerando que la gran mayoría de los documentos de seguridad que he leído de investigadores de renombre sugieren que se estiren las teclas antes de usarlas (ya sea para almacenamiento o cifrado). Y teniendo en cuenta que necesita estirar para el cumplimiento de PCI, no estoy seguro de cómo este es un mal consejo ... – ircmaxell

6

Además de volver a mezclarlo varias veces, usaría una sal diferente para cada contraseña/usuario. Aunque creo que 5000 iteraciones es demasiado, pruebe con un número menor. Hay una compensación aquí; Tendrás que ajustarlo según tus necesidades y tu hardware.

Con diferentes sales para cada contraseña, un atacante se vería obligado a aplicar fuerza bruta a cada contraseña individualmente en lugar de construir una tabla de arco iris, lo que aumenta considerablemente la carga de trabajo.

Como siempre, aquí es una lectura recomendada para esto: Just hashing is far from enough

EDIT: hash iterativo es un perfectly valid tactic. Hay compensaciones, pero todo lo tiene. Si le preocupa el tiempo de cálculo, ¿por qué no simplemente almacena la contraseña de texto plano?

+0

¿Qué pasa? ¿Qué está pasando aquí? – Will

0

La razón del hashing iterativo es hacer que el proceso sea lo más lento posible. Entonces puede hacerlo aún mejor: use diferentes sales para cada iteración. Se puede hacer encriptando sus datos originales una y otra vez en cada iteración con la clave fija y XORing con valor de sal.

+0

¿Podría proporcionar una referencia sobre por qué utilizar sales múltiples es aún mejor? – NikiC

+0

Nada en documentos académicos, en realidad. Simplemente obliga al atacante a realizar un cifrado más en cada ciclo y hace que cualquier precomputación con hash sea imposible, ya que no habrá datos repetitivos. – blaze

+0

La salazón única no hace que la precomputación sea imposible, simplemente limita la utilidad de una tabla de arcoiris generada para descifrar un solo hash. –

0

Prefiero ir con un doble sha1 con dos sales diferentes y evitar que DoS retrase la respuesta de forma incremental (con un simple usleep) por cada comprobación de contraseña inválida.

+1

Creo que exactamente usando usleep hace que su aplicación sea vulnerable. PHP es un lenguaje de bloqueo síncrono, por lo tanto, dormir bloqueará el proceso de PHP. De esta forma, podría hacer que el servidor no responda al hacer menos conexiones que las que necesitaría sin la suspensión;) – NikiC

+1

No solo bloqueará PHP con sus máximas ejecuciones paralelas, sino también el servidor web con sus solicitudes máximas que puede manejar en paralelo (ver por ejemplo, Slowloris; solicitudes lentas para bajar servidores web Apache, etc.). Es al revés: usleep ayuda con ataques de inicio de sesión de fuerza bruta, pero incluso aumenta la utilidad de este para DoS. – Kissaki

3

Por favor, por favor no ruede su propia criptografía. Esto es para lo que son las bibliotecas como OpenSSL. Aquí hay algunos buenos ejemplos de cómo lo usarías para hacer hashes salados.

Salted Hashes in OpenSSL

+0

Usar OpenSSL para crear hashes es prácticamente imposible de usar. Rara vez tienes acceso a la línea de comandos desde PHP y parece que lo necesitas. Además, no veo por qué no debería "rodar [mi] propia criptografía". Simplemente asumo que a) sha512 es mejor que sha1 b) la salazón es buena yc) que el estiramiento es bueno. Por lo tanto, mejoro mi enfoque sha1 original de tres maneras diferentes y no veo por qué esto será malo. – NikiC

+1

¿Cómo es imposible utilizar una biblioteca estándar muy popular? El acceso a la línea de comando no es necesario, ya que la funcionalidad criptográfica básica suele estar bien definida en las llamadas a funciones de cualquier idioma que necesite. No estaba diciendo cortar a ciegas las órdenes del enlace, estaba diciendo que esto ya se había hecho antes, así que no hay necesidad de reinventar la rueda, eso es incorrecto. – Marcin

Cuestiones relacionadas