Estaba leyendo uno de los artículos de DavidHayden sobre Hashing User Passwords .
Realmente no puedo entender lo que está tratando de lograr.
Aquí está su código:
private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}
¿Hay algún otro método de C # para cambiar las contraseñas y agregarle sal?
SHA1
no es de grado criptográfico, por lo que al menos debería usarloSHA256
, que genera 256 bits o 32 bytes. PERO, 256 bits NO es fácilmente convertible a base 64, porque cada carácter base64 codifica 6 bits, y 256 no es divisible por 6. Por lo tanto, necesita un denominador común de 6 (para base64) y 8 (para bits en un byte) más de 256 bits, que son 264 mordidas o 33 bytes. TLDR: uso 33.Respuestas:
En realidad, esto es un poco extraño, con las conversiones de cadenas, que el proveedor de membresía hace para colocarlas en archivos de configuración. Los hashes y las sales son blobs binarios, no es necesario convertirlos en cadenas a menos que desee colocarlos en archivos de texto.
En mi libro, Beginning ASP.NET Security , (oh, finalmente, una excusa para enredar el libro) hago lo siguiente
La generación de sal es como el ejemplo en la pregunta. Puede convertir texto en matrices de bytes usando
Encoding.UTF8.GetBytes(string)
. Si debe convertir un hash a su representación de cadena, puede usarloConvert.ToBase64String
yConvert.FromBase64String
volverlo a convertir.Debe tener en cuenta que no puede usar el operador de igualdad en las matrices de bytes, comprueba las referencias y, por lo tanto, simplemente debe recorrer ambas matrices comprobando cada byte de esta manera
Utilice siempre una nueva sal por contraseña. Las sales no tienen que mantenerse en secreto y pueden almacenarse junto con el hash mismo.
fuente
return array1.Length == array2.Length && !array1.Where((t, i) => t != array2[i]).Any();
Lo que dijo Blowdart, pero con un poco menos de código. Use Linq o
CopyTo
para concatenar matrices.Linq también tiene una manera fácil de comparar sus conjuntos de bytes.
Sin embargo, antes de implementar algo de esto, mira esta publicación . Para el hash de contraseñas, es posible que desee un algoritmo de hash lento, no uno rápido.
Para ese fin está la
Rfc2898DeriveBytes
clase que es lenta (y puede hacerse más lenta), y puede responder a la segunda parte de la pregunta original en que puede tomar una contraseña y sal y devolver un hash. Vea esta pregunta para más información. Tenga en cuenta que Stack Exchange está utilizandoRfc2898DeriveBytes
para el hash de contraseña (código fuente aquí ).fuente
He estado leyendo que las funciones de hash como SHA256 en realidad no estaban destinadas al uso para almacenar contraseñas: https://patrickmn.com/security/storing-passwords-securely/#notpasswordhashes
En cambio, las funciones de derivación de teclas adaptativas como PBKDF2, bcrypt o scrypt eran. Aquí hay uno basado en PBKDF2 que Microsoft escribió para PasswordHasher en su biblioteca Microsoft.AspNet.Identity:
Tenga en cuenta que esto requiere el paquete nuget Microsoft.AspNetCore.Cryptography.KeyDerivation instalado que requiere .NET Standard 2.0 (.NET 4.6.1 o superior). Para versiones anteriores de .NET ver Crypto clase de la biblioteca System.Web.Helpers de Microsoft.
Actualización de noviembre de 2015
Respuesta actualizada para usar una implementación de una biblioteca de Microsoft diferente que utiliza el hashing PBKDF2-HMAC-SHA256 en lugar de PBKDF2-HMAC-SHA1 (tenga en cuenta que PBKDF2-HMAC-SHA1 sigue siendo seguro si iterCount es lo suficientemente alto). Puede consultar la fuente desde la que se copió el código simplificado, ya que en realidad maneja la validación y la actualización de los hash implementados de la respuesta anterior, útil si necesita aumentar iterCount en el futuro.
fuente
PBKDF2SubkeyLength
a 20 bytes. Ese es el tamaño natural f SHA1 y aumentarlo más allá de eso ralentiza al defensor sin ralentizar al atacante. 2) Recomiendo aumentar el recuento de iteraciones. Recomiendo 10k a 100k dependiendo de su presupuesto de rendimiento. 3) Una comparación de tiempo constante tampoco haría daño, pero no tiene mucho impacto práctico.La sal se usa para agregar un nivel adicional de complejidad al hash, para dificultar el craqueo por fuerza bruta.
De un artículo en Sitepoint :
No hay ningún método que haga esto automáticamente en .NET, por lo que tendrá que ir con la solución anterior.
fuente
Creé una clase que tiene el siguiente método:
Validar entrada
``
fuente
Bah, esto es mejor! http://sourceforge.net/projects/pwdtknet/ y es mejor porque ..... realiza estiramiento de claves y usa HMACSHA512 :)
fuente
He creado una biblioteca SimpleHashing.Net para facilitar el proceso de hashing con las clases básicas proporcionadas por Microsoft. SHA ordinario ya no es suficiente para tener las contraseñas almacenadas de forma segura.
La biblioteca usa la idea del formato hash de Bcrypt, pero como no hay una implementación oficial de MS, prefiero usar lo que está disponible en el marco (es decir, PBKDF2), pero es un poco demasiado difícil de usar.
Este es un ejemplo rápido de cómo usar la biblioteca:
fuente
Así es como lo hago. Creo el hash y lo
ProtectedData
almaceno usando la API:fuente
Leí todas las respuestas y creo que son suficientes, especialmente los artículos de @Michael con hashing lento y los buenos comentarios de @CodesInChaos , pero decidí compartir mi fragmento de código para el hashing / validación que puede ser útil y no requiere [ Microsoft.AspNet.Cryptography .KeyDerivation ].
Preste atención a la función SlowEquals que es tan importante. Finalmente, espero que esto ayude y no dude en aconsejarme acerca de mejores enfoques.
fuente
Use el
System.Web.Helpers.Crypto
paquete NuGet de Microsoft. Agrega automáticamente sal al hachís.Hash una contraseña como esta:
var hash = Crypto.HashPassword("foo");
Verifica una contraseña como esta:
var verified = Crypto.VerifyHashedPassword(hash, "foo");
fuente
Si no usa asp.net o .net core, también hay una manera fácil en proyectos> = .Net Standard 2.0.
Primero puede establecer el tamaño deseado del hash, sal y número de iteración que está relacionado con la duración de la generación del hash:
Para generar la contraseña hash y salt puedes usar algo como esto:
Para verificar si la contraseña que ingresó el usuario es válida, puede verificar los valores en su base de datos:
La siguiente prueba unitaria muestra el uso:
Microsoft Rfc2898DeriveBytes Source
fuente
En respuesta a esta parte de la pregunta original "¿Existe algún otro método de C # para contraseñas hash"? Puede lograr esto usando ASP.NET Identity v3.0 https://www.nuget.org/packages/Microsoft.AspNet.Identity. EntityFramework / 3.0.0-rc1-final
fuente
fuente
fuente