Implementación de referencia de hash y verificación de contraseña de C #

7

¿Alguien tiene una implementación de referencia (idealmente certificada por un tercero, o aprobada por el gobierno ) de manera unidireccional de una contraseña para C # o Java?

Idealmente, me gustaría ver algo que incluya una técnica de "sal y pimienta" como se menciona aquí , así como cualquier otro técnica de seguridad moderna para validar que podría ser aplicable.

El contenido que quiero proteger es información que el usuario puede recordar, como una contraseña o la respuesta a una pregunta de seguridad.

Si no tiene un ejemplo de código completo, sería útil una descripción general del algoritmo que elegiría, y ejemplos de métodos de salado y salpicadura.

    
pregunta random65537 12.02.2011 - 18:29
fuente

3 respuestas

5

Dado su nuevo requisito "aprobado por el gobierno", supongo que una buena solución sería PBKDF2 de RFC 2898 . Se implementa para .NET en Rfc2898DeriveBytes Class (System.Security.Cryptography) . Es de suponer que desea sustituir SHA-256 por SHA-1 allí.

También acabo de encontrar la contraseña hash bastante segura: fshp que es como PBKDF1 pero con SHA-256 de forma predeterminada. Admite un número variable de iteraciones, de manera predeterminada a 4096. Utiliza sales de 64 bits. Ellos tienen implementaciones allí para .NET, Python, Ruby, Perl, PHP5, Java y JavaScript.

Como se describe y analiza en .net impl de bcrypt - Stack Overflow , parece que para .NET / CLR otra buena opción (aunque no está aprobada por NIST) es BCrypt.net:

y para Java una buena opción es

Creo que ninguno de los dos parece tener el concepto de "pimienta" o la complejidad de espacio de scrypt.

    
respondido por el nealmcb 13.02.2011 - 04:02
fuente
2

Lo básico

El enfoque básico es Hash(secret | salt) , que se almacena junto con la sal. Obviamente, es importante usar un algoritmo hash moderno como una de las variantes de SHA2 (aunque en la actualidad el SHA1 no está totalmente roto como lo está el MD5). Tenga en cuenta que si está almacenando preguntas de desafío de esta manera, probablemente desee Trim() y ToLower() el secreto antes de incluirlo. Esto puede reducir un poco la complejidad, pero las preguntas de seguridad no tienen la intención de tener una alta entropía como una contraseña.

¿Qué pasa con los ataques de fuerza bruta como las tablas Rainbow?

Las preocupaciones sobre los ataques de fuerza bruta se pueden mitigar de dos maneras:

  1. Requieren una cantidad mínima de entropía en el secreto (longitud, complejidad, etc.).
  2. Aumente la cantidad de cálculos necesarios para realizar el hash.

El método utilizado en bcrypt es una buena mejora en el hashing estándar porque aumenta la cantidad de tiempo para calcular el hash en muchos órdenes de magnitud. Básicamente, simplemente separa el iterativamente el secreto muchas veces: Hash(Hash(...Hash(secret | salt)...))

Debido a que la cantidad de tiempo todavía es relativamente pequeña (cientos de milisegundos), no agrega un retraso intolerable al usuario legítimo. Pero puede arruinar los ataques automáticos de fuerza bruta.

Eso no es lo suficientemente bueno

Si la dificultad adicional de bcrypt es insuficiente, intente scrypt . Funciona como bcrypt pero necesita guardar cada hash iterativo en la memoria para una fusión final al final. Esto agrega la misma complejidad de tiempo que bcrypt , pero también aumenta la complejidad del espacio, lo que hace que sea más difícil de implementar en hardware, especialmente en paralelo.

Implementación

Honestamente, no conozco una biblioteca de C # para implementar esto, y mucho menos una "certificada" por algún organismo oficial, pero no sería demasiado difícil. Suponiendo que escriba código seguro para subprocesos y que la verificación de la contraseña se realice en un sistema confiable como un servidor, los problemas de implementación como ataques de canal lateral están minimizados.

Otras lecturas: Esta respuesta a ¿Es BCrypt un buen algoritmo de cifrado para usar en C #? ¿Dónde puedo encontrarlo?

    
respondido por el Justin Morgan 12.02.2011 - 19:57
fuente
1

Respuesta .Net :
Según esta publicación todos -Cng y < strong> -CryptoServiceProvider implementaciones postfijadas desde .Net Cryptography Namespace debe contar con la certificación FIPS, a diferencia de las versiones administradas.

Inconvenientes:

Ventajas:

  • Están certificados por FIPS
  • Los algoritmos de hashing utilizan bcrypt
respondido por el Ioanna 29.08.2018 - 12:49
fuente

Lea otras preguntas en las etiquetas