2010-03-31 7 views
18

Dadas las debilidades conocidas de MD5 y las debilidades recientes (mayo de 2009) discutidas en SHA1, ¿cómo deberían salinizar los nuevos programas & hashing sus contraseñas?¿Cuál es el algoritmo de hashing recomendado para usar para las contraseñas almacenadas?

He visto SHA-256 y SHA-512 sugeridos.

Programación predominantemente en Ruby on Rails y uso de PostgreSQL, pero otros lenguajes y entornos también pueden tener que calcular hash de contraseñas.

+2

Gracias Martin, entiendo que. Era una pregunta limitada y merecía una respuesta estrecha. – Hissohathair

Respuesta

21

SHA-256 y SHA-512 son seguros en el futuro previsible. Pertenecen a la familia SHA-2, contra la cual no se han identificado ataques hasta el momento. This wikipedia page dice que los proveedores de Unix y Linux están ahora cambiando a SHA-2 por su hash seguro de contraseñas. La familia SHA-3, con algoritmos aún más fuertes, se está desarrollando, pero no estará lista hasta 2012 como mínimo.

P.S: A menos que esté ocultando los nombres de los agentes secretos de los gobiernos, también estará a salvo con SHA-1, pero si no tiene problemas para implementar SHA-2, solo use ese en su lugar.

+2

PKCS # 5 (http://www.rsa.com/rsalabs/node.asp?id=2127) analiza otra buena información (como iteraciones) que el lector puede querer considerar. – atk

+2

SHA-1 se considera roto. –

+0

@Noon Silk: ¿cuánta potencia informática se necesita actualmente para romperla? –

17

Utilice una función lenta como bcrypt. Here es una publicación de los chicos de Phusion.

-4

se debe utilizar un nombre de usuario de hash, la contraseña y la sal, como:

hash(length(username)+"_veryuniquesalt4rtLMAO"+username+password) 

De esta manera, la base de datos no es vulnerable a las tablas del arco iris existentes, debido a la sal, y con el nombre de usuario hash junto con la contraseña también es imposible crear una tabla de arcoíris para su método hash específico.

El uso de un algoritmo hash "lento" protegerá mejor las contraseñas, al igual que si fueran más complejas, pero es una compensación, una vez que ha decidido un cierto nivel de lentitud no puede escalar cuando necesita el rendimiento para otras cosas.

También es posible hacer el hashing lento del lado del cliente usando JavaScript, de esa manera no va a ser un problema de rendimiento, pero el método por supuesto requerirá que JavaScript esté habilitado.

No importa lo que elija, un poco de slowhashing es mucho mejor que nada, use 1 milisegundo en lugar de 1 microsegundo y su protección es 1000 veces más fuerte.

Puede usar bcrypt, o puede hacer que un algoritmo de hash convencional haga mucho trabajo adicional, solo asegúrese de que el trabajo adicional no sea principalmente concatenación de cadenas.

Al final, mejor no obtener su base de datos robada, muchas contraseñas son tan débiles que se extraen fácilmente sin importar lo que haga.

+2

Tenga en cuenta que incluir el nombre de usuario en el hash evita cambiar el nombre de usuario. Dependiendo de los requisitos del sistema, esto puede o no ser deseable. Si no es deseable, el uso del uid (o guid, o equivalente) sería una alternativa. – atk

+1

Simplemente tendrá que hacer que el usuario ingrese su contraseña para cambiar el nombre de usuario, mejor práctica de todos modos. – aaaaaaaaaaaa

+2

hay un error muy sutil en su código - usted debe * nunca * concatiar datos en un hash. H (x + y + z) te abre a un ataque de extensión de longitud. En su lugar, debe: H (H (x + y + z)) o H (H (x) + H (y) + H (z)) –

7

Debe utilizar una función de derivación de clave basada en contraseña como el resultado de uid/pwd; el más conocido es PBKDF2 http://en.wikipedia.org/wiki/PBKDF2 también definido como RFC 2898 http://tools.ietf.org/html/rfc2898. PKBDF2 toma sus datos secretos, así como sal y recuento de iteraciones. Esta es la forma estándar de resolver su problema.

Si programa en .NET, utilice Rfc2898DeriveBytes http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

+1

Acabo de leer 100 artículos y preguntas sobre el tema, y ​​parece estar de acuerdo en que RFC2898 o cualquier otra solución de iteración múltiple (por ejemplo, BCrypt) es el camino a seguir. Pero Rfc2898DeriveBytes se basa en SHA-1, ¿no? ¿No está desactualizado? Y BCrypt no parece "validado", a pesar de que se ve genial. Además, Rfc2898DeriveBytes no implementa IDisposable, parece que podría perder la contraseña de texto claro en la memoria con bastante facilidad. Mis necesidades reales no son tan paranoicas, pero quiero medir qué tan seguro es cada cosa. ¿Cuál sería tu opinión sobre eso? ¡Gracias! –

Cuestiones relacionadas