c# - bcrypt net next
¿Contraseña hash en C#? Bcrypt/PBKDF2 (7)
PBKDF2
Estuviste realmente cerca en realidad. El enlace que le ha Rfc2898DeriveBytes le muestra cómo puede llamar a la función Rfc2898DeriveBytes para obtener resultados de hash Rfc2898DeriveBytes . Sin embargo, le sorprendió el hecho de que el ejemplo utilizara la clave derivada para fines de encriptación (la motivación original para PBKDF1 y 2 fue crear funciones de derivación "clave" adecuadas para usar como claves de cifrado). Por supuesto, no queremos utilizar la salida para el cifrado, sino como un hash por sí mismo.
Puede probar la biblioteca SimpleCrypto.Net escrita exactamente para este propósito si desea PBKDF2. Si nos fijamos en la implementación , puede ver que en realidad es solo una capa delgada (lo adivinó) Rfc2898DeriveBytes .
BCrypt
Puede probar la implementación de C # nombrada (qué más) BCrypt.NET si desea experimentar con esta variante.
Descargo de responsabilidad: No he usado ni probado ninguna de las bibliotecas a las que he vinculado ... YMMV
Busqué msdn y otros recursos sobre cómo hacer esto, pero no encontré soluciones claras. Este es el mejor que encontré http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx?Redirected=true
Me gustaría usar contraseñas hash en C # utilizando bcrypt o PBKDF2 (que parece estar relacionado con bcrypt). Me gusta experimentar con cuántas rondas se necesitan para que mi computadora califique una contraseña. Sin embargo, todo parece tratarse de encriptar mientras todos hablan de hash. No puedo resolverlo. ¿Cómo tengo una contraseña? Parece más como PBKDF2 (Rfc2898?) Es un generador de números aleatorios y yo uso GetBytes (cantidad) para elegir qué tan grande es mi tamaño de hash.
Estoy confundido. ¿Cómo exactamente tengo una contraseña con bcrypt / PBKDF?
A principios de este año estaba investigando lo mismo para crear hashes para nuestro proyecto ASP.NET Web Forms, quería hacerlo de la misma manera que los proyectos MVC lo hacen de la caja.
Me encontré con esta pregunta => ASP.NET identidad predeterminada Contraseña Hasher, ¿cómo funciona y es seguro? Luego encontré la fuente con el método ByteArraysEqual aquí => http://www.symbolsource.org/MyGet/Metadata/aspnetwebstacknightly/Project/Microsoft.AspNet.Identity.Core/2.0.0-rtm-140327/Release/Default/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core/Crypto.cs?ImageName=Microsoft.AspNet.Identity.Core
Me llevó una forever (días tomó días) encontrar lo que realmente código para obtener contraseñas hash para trabajar !! así que lo puse aquí por conveniencia.
Necesitas leer la documentation y la theory1 theory2 y algo más o podrías estar abierto a lagunas de seguridad. ¡La seguridad es un tema muy importante! ¡El comprador tenga cuidado!
Agregue el paquete NuGet BCrypt.Net a la solución
const int WorkFactor = 14;
var HashedPassword = BCrypt.Net.BCrypt.HashPassword(Password, WorkFactor);
Debe ajustar el WorkFactor a lo que es apropiado ver discussions . Es una función log2
"El número es log2, por lo que cada vez que las computadoras dupliquen su velocidad, agregue 1 al número predeterminado".
Luego, almacena la contraseña hash en su db como passwordFromLocalDB
y para probar una password
entrante como esta:
if (BCrypt.Net.BCrypt.Verify(password, passwordFromLocalDB) == true)
¡Buena suerte!
PBKDF2
En el ejemplo de Rfc2898DeriveBytes , cuando llegue a la línea "Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes (pwd1, salt1, myIterations); ", k1 es el hash. La razón por la que el ejemplo es para el cifrado es que Rfc2898DeriveBytes se diseñó originalmente para crear claves de cifrado.
Si no proporciona un salt, Rfc2898DeriveBytes lo creará, pero no sé si RNGCryptoServiceProvider hace un mejor trabajo al ser criptográficamente aleatorio.
De acuerdo con OWASP ( https://www.owasp.org/index.php/Using_Rfc2898DeriveBytes_for_PBKDF2 ), el uso subyacente de SHA1 por Rfc2898DeriveBytes significa que solo es bueno para hashes de hasta 160 bits de longitud. Si crea un hash más largo, un atacante solo tiene que preocuparse por los primeros 160 bits, pero ha hecho que el hashing / autenticación de contraseña sea más caro para usted sin ganancia.
Aquí hay un código de ejemplo para el hash de contraseñas Rfc2898DeriveBytes (almacene el hash, sal e iteraciones en el DB):
public class Rfc2898PasswordEncoder
{
private int _byteLength = 160 / 8; // 160 bit hash length
public class EncodedPassword
{
public byte[] Hash { get; set; }
public byte[] Salt { get; set; }
public int Iterations { get; set; }
}
public EncodedPassword EncodePassword(string password, int iterations)
{
var populatedPassword = new EncodedPassword
{
Salt = CreateSalt(),
Iterations = iterations
};
// Add Hash
populatedPassword.Hash = CreateHash(password, populatedPassword.Salt, iterations);
return populatedPassword;
}
public bool ValidatePassword(string password, EncodedPassword encodedPassword)
{
// Create Hash
var testHash = CreateHash(password, encodedPassword.Salt, encodedPassword.Iterations);
return testHash == encodedPassword.Hash;
}
public byte[] CreateSalt()
{
var salt = new byte[_byteLength]; // Salt should be same length as hash
using (var saltGenerator = new RNGCryptoServiceProvider())
{
saltGenerator.GetBytes(salt);
}
return salt;
}
private byte[] CreateHash(string password, byte[] salt, long iterations)
{
byte[] hash;
using (var hashGenerator = new Rfc2898DeriveBytes(password, salt, (int)iterations))
{
hash = hashGenerator.GetBytes(_byteLength);
}
return hash;
}
}
PBKDF2 usa HMACSHA1, si desea una solución más moderna y personalizable, debe mirar esta API usando HMACSHA256 o 512 con la tecla de estiramiento al igual que PBKDF2
https://sourceforge.net/projects/pwdtknet/
La GUI de muestra incluida en el código fuente demostró cómo obtener un hash de una contraseña, incluida la creación de sal criptográfica al azar ..... disfrutar :)
Para PBKDF2, es posible que pueda usar System.Security.Cryptography.Rfc2898DeriveBytes.
Vea MSDN aquí: Rfc2898DeriveBytes
estaba interesado en respuestas que no involucraban ninguna biblioteca.
Leí este artículo https://crackstation.net/hashing-security.htm que vincula una implementación en diferentes idiomas C # entre ellos, que también voy a vincular aquí
https://github.com/defuse/password-hashing/blob/master/PasswordStorage.cs
curiosamente utiliza Rfc2898DeriveBytes como se menciona un par de veces aquí.
private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes){
using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt)) {
pbkdf2.IterationCount = iterations;
return pbkdf2.GetBytes(outputBytes);
}
}