asp.net - route - input asp for
¿La membresía de ASP.NET es sal? (3)
¿Cómo la membresía ASP.NET genera su clave de sal y luego cómo la codifican (es decir, es sal + contraseña o contraseña + sal)?
Estoy usando SHA-1 con mi membresía, pero me gustaría volver a crear las mismas sales para que las cosas de membresía incorporadas puedan distorsionar las cosas de la misma manera que mis cosas.
Edición 2: No importa. Lo leí mal y pensé que decía bytes, no bits. Así que estaba pasando en 128 bytes, no en 128 bits.
Edit: He estado tratando de hacerlo así. Esto es lo que tengo,
public string EncodePassword(string password, string salt)
{
byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] src = Encoding.Unicode.GetBytes(salt);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
private byte[] createSalt(byte[] saltSize)
{
byte[] saltBytes = saltSize;
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
return saltBytes;
}
Por lo tanto, no he intentado ver si la membresía de ASP.NET reconocerá esto, pero la contraseña de hash parece cercana. Simplemente no sé cómo convertirlo a base64 para la sal.
hice esto
byte[] storeSalt = createSalt(new byte[128]);
string salt = Encoding.Unicode.GetString(storeSalt);
string base64Salt = Convert.ToBase64String(storeSalt);
int test = base64Salt.Length;
La longitud de la prueba es 172, que está muy por encima de los 128 bits. ¿Qué estoy haciendo mal?
Así es como se ve su sal.
vkNj4EvbEPbk1HHW+K8y/A==
Así es como se ve mi sal.
E9oEtqo0livLke9+csUkf2AOLzFsOvhkB/NocSQm33aySyNOphplx9yH2bgsHoEeR/aw/pMe4SkeDvNVfnemoB4PDNRUB9drFhzXOW5jypF9NQmBZaJDvJ+uK3mPXsWkEcxANn9mdRzYCEYCaVhgAZ5oQRnnT721mbFKpfc4kpI=
Aquí es cómo SQLMembershipProvider genera sal.
private string GenerateSalt() {
var buf = new byte[16];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}
Puede descargar el código del proveedor SQL de ASP.NET here .
El problema que estaba teniendo era una aplicación de desarrollo que se ejecuta en IIS7. .NET 4.0 usaba un algoritmo hash predeterminado diferente al HashAlgorithmType predeterminado para .NET 2.0.
En el código de ejemplo de "EncodePassword" de Microsoft, hacen referencia a Membership.HashAlgorithmType
que creo que devuelve el valor predeterminado para el marco, si no se especifica en web.config
.
Pude conseguir que tanto este método GenerateSalt como EncodePassword funcionen para mi aplicación.
Mi código combinado:
internal string GenerateSalt()
{
byte[] buf = new byte[16];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}
internal string EncodePassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0) // MembershipPasswordFormat.Clear
return pass;
byte[] bIn = Encoding.Unicode.GetBytes(pass);
byte[] bSalt = Convert.FromBase64String(salt);
byte[] bAll = new byte[bSalt.Length + bIn.Length];
byte[] bRet = null;
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
if (passwordFormat == 1)
{ // MembershipPasswordFormat.Hashed
HashAlgorithm s = HashAlgorithm.Create("SHA1");
// Hardcoded "SHA1" instead of Membership.HashAlgorithmType
bRet = s.ComputeHash(bAll);
}
else
{
bRet = EncryptPassword(bAll);
}
return Convert.ToBase64String(bRet);
}
Aquí hay una forma de hacerlo. Una sal es solo un número aleatorio, puede usar la clase RNGCryptoServiceProvider en la biblioteca del marco para producir un buen número aleatorio para usar como sal
private const int ITERATIONS = 10000;
private const int SALT_SIZE = 32;
private const int HASH_SIZE = 32;
public void SaltAndHashPassword(string password, out byte[] salt,
out byte[] hash)
{
Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(
password,
SALT_SIZE,
ITERATIONS);
salt = rdb.Salt;
hash = rdb.GetBytes(HASH_SIZE);
}
¿Qué es el algoritmo hash predeterminado que utiliza la pertenencia a ASP.NET? Tiene una buena discusión de su algoritmo por defecto.
¡Espero que eso ayude!
Editar- La respuesta a la que me refería es el código en la publicación superior,
public string EncodePassword(string pass, string salt)
{
byte[] bytes = Encoding.Unicode.GetBytes(pass);
//byte[] src = Encoding.Unicode.GetBytes(salt); Corrected 5/15/2013
byte[] src = Convert.FromBase64String(salt);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
Ellos están combinando Unicode Salt + Pass usando BlockCopy
- En respuesta a tu pregunta:
Ambos algoritmos son necesarios y cumplen diferentes roles ...
RNG Crypto se utiliza para generar la sal. Es básicamente una larga cadena de datos aleatorios. Esto se genera y almacena por usuario. Normalmente esto se hace cuando se crea un usuario o se cambia una contraseña.
BlockCopy es solo el método que usan para combinar el salt con la contraseña. El código anterior esencialmente equivale a salt + contraseña.
No podrás recrear un valor de sal ya que es completamente aleatorio. Sin embargo, se almacena para cada usuario por el marco.
Combinar el salt con la contraseña y hacer hash con la técnica anterior le permitirá verificar las contraseñas de los usuarios con el valor hash almacenado por el marco.
Creo que ambos leemos su pregunta de manera diferente. El código que publiqué no generará su sal, pero le permitirá usarlo de una manera que sea compatible con la membresía ASP.NET.
Lo siento, mi explicación no es la mejor. ¿Eso responde a tu pregunta?