2009-08-12 19 views
20

¿Cómo genera la membresía de ASP.NET su clave salt y luego cómo la codifican (es decir, es salt + password o password + salt)?¿Sal de miembro de ASP.NET?

Estoy usando SHA-1 con mi membresía, pero me gustaría recrear las mismas sales para que la membresía incorporada pueda hacer hash de la misma manera que mis cosas.

Editar 2: No importa. Lo leí mal y estaba pensando que decía bytes, no bits. Así que estaba pasando en 128 bytes, no en 128 bits.

Edit: He estado intentando que sea 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; 
} 

así que no he tratado de ver si la suscripción de ASP.NET lo reconocerá sin embargo, el hash de la contraseña parece estar cerca. Simplemente no sé cómo convertirlo a base64 para la sal.

lo hice

byte[] storeSalt = createSalt(new byte[128]); 
string salt = Encoding.Unicode.GetString(storeSalt); 
string base64Salt = Convert.ToBase64String(storeSalt); 

int test = base64Salt.Length; 

Probar la longitud es de 172, que está muy por encima de los 128 bits por lo que lo que estoy haciendo mal?

Esto es lo que se ve como su sal

vkNj4EvbEPbk1HHW+K8y/A== 

Esto es lo que parece mi sal como

E9oEtqo0livLke9+csUkf2AOLzFsOvhkB/NocSQm33aySyNOphplx9yH2bgsHoEeR/aw/pMe4SkeDvNVfnemoB4PDNRUB9drFhzXOW5jypF9NQmBZaJDvJ+uK3mPXsWkEcxANn9mdRzYCEYCaVhgAZ5oQRnnT721mbFKpfc4kpI= 
+0

Usted puede comprobar mi respuesta en este SO página: http://stackoverflow.com/questions/530426/reimplement-asp-net-membership-and- user-password-hashing-in-ruby/8184569 # 8184569 –

Respuesta

18

What is default hash algorithm that ASP.NET membership uses? tiene una buena discusión sobre su algoritmo predeterminado.

Espero que ayude!

Editar- La respuesta me refiero es el código en el puesto más alto,

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 Sal + Pass usando BlockCopy

- En respuesta a su pregunta:

Ambos algoritmos son necesarios y cumplen diferentes roles ...

RNG Crypto se utiliza para generar la sal. Básicamente es una larga cadena de datos aleatorios. Esto se genera y almacena por usuario. Por lo general, esto se hace cuando se crea un usuario o se cambia una contraseña.

BlockCopy es simplemente el método que utilizan para combinar la sal con la contraseña. El código anterior esencialmente equivale a sal + contraseña.

No podrá recrear un valor de sal ya que es completamente aleatorio. Sin embargo, está almacenado para cada usuario por el marco.

Combinando la sal con la contraseña y hashing utilizando la técnica anterior le permitirá verificar las contraseñas de los usuarios utilizando 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 de ASP.NET.

Disculpa, mi explicación no es la mejor. ¿Responde eso a tu pregunta?

+0

No le dice cómo Microsoft hace la sal. –

+0

La publicación superior muestra el algoritmo; la he copiado aquí para mayor claridad. –

+0

Lo siento, veo lo que quieres decir. Supuse que estaba buscando cómo se combinó para recrear de los datos existentes. –

1

Aquí hay una forma de hacerlo. Una sal es sólo un número al azar, puede utilizar la clase RNGCryptoServiceProvider en la biblioteca de marco para producir un buen número al azar para su uso 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); 
} 
+0

Hola He encontrado en MSDN este "PasswordSalt: valor de 128 bits generado aleatoriamente usado para hashes de contraseñas de sal; almacenado en forma de base-64-codificada" http://msdn.microsoft.com/en-us/library /aa478949.aspx Entonces, ¿qué haría hasta salt_size a 128? ¿Qué tal el tamaño de hash? – chobo2

+0

también tienen este MembershipPasswordFormat.Hashed (valor predeterminado), que almacena hashes salados generados a partir de contraseñas y respuestas de contraseña. La sal es un valor aleatorio de 128 bits generado por la clase RNGCryptoServiceProvider de .NET Framework. Cada par de respuestas de contraseña/contraseña se sala con este valor único, y la sal se almacena en el campo PasswordSalt de la tabla aspnet_Membership. El resultado de hash la contraseña y la sal se almacena en el campo Contraseña. Del mismo modo, el resultado de hash la respuesta de contraseña y el salt se almacena en el campo PasswordAnswer. – chobo2

+0

me hace preguntarme si es Password + Salt. – chobo2

19

Así es como el SqlMembershipProvider genera sal.

private string GenerateSalt() { 
     var buf = new byte[16]; 
     (new RNGCryptoServiceProvider()).GetBytes(buf); 
     return Convert.ToBase64String(buf); 
    } 

Usted puede descargar el código SQL del proveedor ASP.NET here.

El problema que estaba teniendo era una aplicación de desarrollo ejecutándose en IIS7. .NET 4.0 estaba usando un algoritmo hash predeterminado diferente al HashAlgorithmType predeterminado para .NET 2.0.

En el "EncodePassword" código de ejemplo de Microsoft, que hacen referencia Membership.HashAlgorithmType que creo que vuelve el valor predeterminado para el marco, si no se especifica en el web.config.

Pude obtener este método GenerateSalt y EncodePassword 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); 
} 
+3

RhinoDevX64, ¡tu respuesta fue exactamente lo que estaba buscando! ¡Muchas gracias, terminaron mi lucha de días tratando de descubrir cómo comparar mis cadenas con la información de hash/salt en la base de datos! –