TL; DR use Microsoft.AspNetCore.Cryptography.KeyDerivation, implementando PBKDF2 con SHA-512.
La buena idea para empezar a usar hash de contraseñas es observar qué dice OWASP guidelines. La lista de algoritmos recomendados incluye Argon2, PBKDF2, scrypt y bcrypt. Todos estos algoritmos se pueden sintonizar para ajustar el tiempo que lleva codificar una contraseña y, en consecuencia, el tiempo para descifrarla mediante la fuerza bruta. Todos estos algoritmos utilizan sal para protegerse de los ataques de tablas del arco iris.
Ninguno de estos algoritmos es terriblemente débil, pero hay algunas diferencias:
- bcrypt ha existido desde hace casi 20 años, ha sido ampliamente utilizado y ha resistido la prueba del tiempo. Es bastante resistente a los ataques de GPU , pero no a FPGA
- Argon2 es la última incorporación, siendo un ganador de la competencia de hash de contraseñas de 2015. Tiene una mejor protección contra los ataques de GPU y FPGA, pero es demasiado reciente para mi gusto
- No sé mucho sobre scrypt. Ha sido diseñado para frustrar ataques acelerados de GPU y FPGA, pero he escuchado que resultó ser menos fuerte que originalmente
- PBKDF2 es una familia de algoritmos parametrizados por las diferentes funciones de hash . No ofrece una protección específica contra ataques GPU o ASIC, especialmente si se utiliza una función hash más débil como SHA-1, pero está certificada por FIPS si es importante para usted, y aún aceptable si el número de iteraciones es lo suficientemente grande.
Basado solo en algoritmos, probablemente iría con bcrypt, siendo PBKDF2 el menos favorable.
Sin embargo, no es la historia completa, porque incluso el mejor algoritmo puede quedar inseguro por una mala implementación. Veamos lo que está disponible para la plataforma .NET:
- Bcrypt está disponible a través de bcrypt.net. Dicen que la implementación se basa en Java jBCrypt. Actualmente hay 6 contribuyentes y 8 números (todos cerrados) en github. En general, se ve bien, sin embargo, no sé si alguien ha realizado una auditoría del código, y es difícil saber si una versión actualizada estará disponible lo suficientemente pronto si se encuentra una vulnerabilidad. Escuché que Stack Overflow dejó de usar bcrypt por estos motivos
- Probablemente la mejor forma de utilizar Argon2 sea a través de enlaces a la conocida biblioteca libsodium , p. Ej. https://github.com/adamcaudill/libsodium-net. La idea es que la mayor parte de la criptografía se implementa a través de libsodium, que tiene un considerable soporte de , y las partes "no probadas" son bastante limitadas.Sin embargo, en detalles de criptografía significan mucho, por lo que combinado con ARGON2 siendo relativamente reciente, me tratan como una opción experimental
- Durante mucho tiempo, .NET tenía un sistema incorporado en una implementación de PBKDF2 través Rfc2898DeriveBytes clase. Sin embargo, la implementación solo puede usar la función hash SHA-1, que se considera demasiado rápida para ser segura hoy en día
- Finalmente, la solución más reciente es Microsoft.AspNetCore.Cryptography.KeyDerivation paquete disponible a través de NuGet. Proporciona el algoritmo PBKDF2 con funciones hash SHA-1, SHA-256 o SHA-512, que es considerablemente mejor que
Rfc2898DeriveBytes
. La mayor ventaja aquí es que la implementación es proporcionada por Microsoft, y si bien no puedo evaluar adecuadamente la diligencia criptográfica de los desarrolladores de Microsoft frente a los desarrolladores de BCrypt.net o libsodium, simplemente tiene sentido confiar en ello, porque si está ejecutando una aplicación .NET, están confiando mucho en Microsoft ya. También podríamos esperar que Microsoft publique actualizaciones si se encuentran problemas de seguridad. Ojalá.
para resumir la investigación hasta este punto, mientras que PBKDF2 podría ser el algoritmo menos preferido de los cuatro, la disponibilidad de aplicación suministrado por Microsoft triunfa sobre la que, por lo que la decisión razonable sería utilizar Microsoft.AspNetCore.Cryptography.KeyDerivation
.
El paquete reciente en este momento está destinado a .NET Standard 2.0, por lo que está disponible en .NET Core 2.0 o .NET Framework 4.6.1 o posterior. Si utiliza la versión anterior del marco, es posible usar la versión anterior del paquete, 1.1.3, que apunta a .NET Framework 4.5.1 o .NET Core 1.0. Desafortunadamente, no es posible usarlo incluso en versiones anteriores de .NET.
La documentación y el ejemplo de trabajo están disponibles en docs.microsoft.com. Sin embargo, no lo copie y pegue como está, todavía hay decisiones que un desarrollador debe tomar.
La primera decisión es qué función hash usar. Las opciones disponibles incluyen SHA-1, SHA-256 y SHA-512. De ellos, SHA-1 es definitivamente demasiado rápido para ser seguro, SHA-256 es decente, pero recomendaría SHA-512, porque supuestamente, su uso de operaciones de 64 bits hace que sea más difícil beneficiarse de los ataques basados en GPU.
Luego, tiene que elegir la longitud de salida del hash de la contraseña y la longitud de la sal. No tiene sentido tener una salida más larga que la salida de la función hash (por ejemplo, 512 bits para SHA-512), y probablemente sería la más segura tenerlo exactamente así. Para la duración de la sal, las opiniones difieren. 128 bits deberían ser suficientes, pero en cualquier caso, la longitud más larga que la longitud de la salida de hash seguramente no proporciona ningún beneficio.
A continuación, hay un recuento de iteraciones. Cuanto más grande es, los hash de contraseñas más difíciles son para descifrar, pero cuanto más tiempo lleva registrar a los usuarios. Sugiero elegirlo, por lo que el hash toma entre 0,25 y 1 segundo en el sistema de producción típico, y en cualquier caso, no debe ser inferior a 10000.
Normalmente, obtendrá una matriz de bytes como valores de sal y hash. Use Base64 para convertirlos en cadenas. Puede optar por usar dos columnas diferentes en la base de datos, o combinar sal y contraseña en una columna usando un separador que no se encuentra en Base64.
No olvide idear un almacenamiento de hash de contraseña de forma que permita avanzar sin problemas a un mejor algoritmo de hash en el futuro.
¿Qué vas a hacer con la contraseña hash? Almacenarlo en una base de datos? Entonces simplemente hashing no es suficiente ([Rainbow table] (http://en.wikipedia.org/wiki/Rainbow_table)). Use sales. – dtb
Voy a almacenarlo en una base de datos. Que recomiendas. – Sean
Personas, tenga en cuenta que las respuestas a continuación están desactualizadas. Y tenga en cuenta que nunca más debe usar MD5 para la contraseña hash. Es viejo, roto y obsoleto. La solución más fácil, actualizada y segura para la mayoría de las personas sería [bcrypt] (https://bcrypt.codeplex.com/). Al menos cuando se escribió este comentario :) Argon2 probablemente será la recomendación estándar pronto. – Sammi