.net - originales - Contraseña segura Hashing
generador de contraseñas wifi (9)
Necesito almacenar un hash de una sola contraseña en una aplicación .Net WinForms.
¿Cuál es la forma más segura de hacer esto?
En particular:
- ¿Sal, HMAC, o ambos?
- ¿Cuánta sal?
- ¿Cuántas iteraciones?
- ¿Qué codificación? (La contraseña es ASCII simple)
Supongo que el algoritmo debe ser SHA512 o HMACSHA512.
Aquí hay una API que hará todo lo que necesitas / quieres :)
Creo que deberías seguir con los estándares abiertos. Entre los esquemas hash actuales, el "{ssha}" utilizado por OpenLDAP es muy seguro y ampliamente utilizado. Puedes encontrar la descripción aquí,
http://www.openldap.org/faq/data/cache/347.html
La mayoría de las bibliotecas LDAP implementan este esquema.
Hash y sal. Si solo hash, podrías ser atacado por un ataque de arco iris (la búsqueda inversa) y una sal hace que esto sea mucho más difícil (la sal aleatoria sería la mejor). Para tu codificación probablemente querrás que Base64 o Hex codifiquen la matriz de bytes resultante. . Si solo intenta almacenar la matriz de bytes como Unicode, podría correr el riesgo de perder algunos datos porque no todos los patrones son caracteres válidos. Esto también permite una manera más fácil de comparar hashes (simplemente compare la cadena base64 o hexadecimal cuando desee validar en lugar de comparar la matriz de bytes)
Un mayor número de rondas no hace mucho más que reducir la velocidad que tendrían los atacantes. Pero también es mucho más difícil reutilizar los hash en el futuro si pierde o necesita recrear su algoritmo de hash. Puede revisar un hash de contraseña estándar como crypt en sistemas UNIX. Esto le permite cambiar el algoritmo hash e incluso puede admitir el control de versiones.
Pero nuevamente, un simple hash + salt es lo suficientemente bueno para la mayoría de las aplicaciones.
Mirando estrictamente a más seguro:
Salt, HMAC, or both?
Ambos serían más seguros. Dado que la clave para el HMAC podría considerarse una sal, hacer ambas cosas sería un poco redundante, pero aún más seguro porque se necesitaría más trabajo para resolverlo.
How much salt?
Cada bit de sal duplicaría las combinaciones que deberían mantenerse en una tabla de arco iris para descifrar fácilmente la contraseña. Pero como solo hay una contraseña, y solo una sal, es posible que no se necesite más. El HMAC usa el tamaño de bloque del hash subyacente para su tamaño de clave, 1024 bits para SHA512. El tamaño del bloque debería ser lo suficientemente bueno para la sal, pero duplicarlo o triplicarlo haría que descifrar la contraseña con una tabla arco iris fuera mucho más difícil.
How many iterations?
Mientras más, mejor. Claro, más iteraciones significa que tomará más tiempo determinar si se ingresó la contraseña correcta, pero las computadoras son rápidas y a los usuarios no les importará esperar unos segundos mientras verifican la contraseña. Hacer más iteraciones significaría que alguien que descifre la contraseña también tendría que hacer más iteraciones.
What encoding? (The password is plain ASCII)
También podría encriptar (con AES) la contraseña super-segura, iterada, salada, HMAC''ed junto con su sal para hacerla más difícil. Haga que la contraseña para el hash y la clave cifrados sea una combinación de cadenas que deberían aparecer en el ejecutable, como "RNGCryptoServiceProvider" o "System.Security.Cryptography". Y mientras codificamos, también podríamos convertirlo en hexadecimal, base64, o mejor aún, base-36 o alguna otra conversión menos esperada.
Nota: Esto se escribió principalmente en broma, pero aún debería contener algo de verdad.
Para una implementación del lado del servidor con un gran número de contraseñas, definitivamente debería usar un enfoque iterable ajustable como bcrypt. Este conocido artículo sobre el tema sigue siendo (en su mayoría) relevante:
http://www.securityfocus.com/blogs/262
Para una contraseña única en una aplicación independiente, donde la ubicación de almacenamiento probablemente ya esté protegida por el propio sistema de autenticación del sistema, creo que es mucho menos importante. Un solo hash fuerte es probablemente lo suficientemente bueno, y agregar sal es tan fácil que no hay razón para no hacerlo.
Puedes seguir un estándar publicado, como pkcs # 5. vea http://en.wikipedia.org/wiki/PKCS para una breve descripción, o http://tools.ietf.org/html/rfc2898 para el RFC.
Puedo recomendar BCrypt.net . Muy fácil de usar y puede ajustar el tiempo que tomará hacer el hash, ¡lo que es increíble!
// Pass a logRounds parameter to GenerateSalt to explicitly specify the
// amount of resources required to check the password. The work factor
// increases exponentially, so each increment is twice as much work. If
// omitted, a default of 10 is used.
string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
// Check the password.
bool matches = BCrypt.CheckPassword(candidate, hashed);
Sal de su hash con sal aleatoria segura de al menos 128 bits o más, para evitar un ataque de arco iris y utilice BCrypt , BCrypt o scrypt . PBKDF2 viene con la aprobación NIST .
El problema es que MD5 es rápido. También lo son sus competidores modernos, como SHA1 y SHA256. La velocidad es un objetivo de diseño de un hash seguro moderno, porque los hashes son un componente básico de casi todos los sistemas criptográficos y, por lo general, se ejecutan según demanda por paquete o por mensaje.
La velocidad es exactamente lo que no quieres en una función de hash de contraseña.
Las funciones de validación rápida de contraseñas son un problema, ya que pueden ser atacadas usando fuerza bruta. Con todos los algoritmos anteriores puedes controlar la "lentitud"
RNGCryptoServiceProvider para generar un salt aleatorio, luego SHA512 la contraseña con el salt, y finalmente almacena el hash de la contraseña y el salt correspondiente si deseas verificar más tarde que algún texto es igual a la contraseña almacenada.