2010-03-30 7 views
12

Utilizzo un sito Web come frontend e tutti gli utenti sono autenticati con il provider di appartenenza ASP.NET standard. Le password vengono salvate "hash" all'interno di un database SQL.Come creare un hash password del provider di appartenenza asp.net manualmente?

Ora voglio scrivere un client desktop con funzioni amministrative. Tra le altre cose dovrebbe esserci un metodo per reimpostare la password di un utente. Posso accedere al database con i dati di appartenenza salvati, ma come posso creare manualmente la password-salt e -hash? L'uso dello spazio dei nomi System.Web.Membership sembra inappropriato, quindi ho bisogno di sapere come creare manualmente il sale e l'hash della nuova password.

Gli esperti aumentano! :)

+2

Perché System.Web.Security appropriati? Sembra lo strumento giusto per il lavoro. –

+0

Non riesco a includere un provider di appartenenze in un'applicazione client desktop, utilizzando il mio database sql, posso? Quando è possibile hai ragione e posso usare questi metodi ... ma come implementarlo? – Anheledir

risposta

13

si può assolutamente utilizzare System.Web.Security all'interno di una console o WinForms app.

Ecco una semplice applicazione console:

static void Main(string[] args) 
{ 
    MembershipProvider provider = Membership.Provider; 

    MembershipUser myUser = provider.GetUser("myUser", false); 

    if(myUser != null) provider.DeleteUser("myUser", true); 

    MembershipCreateStatus status; 

    myUser = provider.CreateUser("myUser", "password", "[email protected]", null, null, true, null, out status); 

    if (status != MembershipCreateStatus.Success) 
    { 
     Console.WriteLine("Could not create user. Reason: " + status.ToString()); 
     Console.ReadLine(); 
     return; 
    } 

    Console.WriteLine("Authenticating with \"password\": " + provider.ValidateUser("myUser", "password").ToString()); 

    string newPassword = myUser.ResetPassword(); 

    Console.WriteLine("Authenticating with \"password\": " + provider.ValidateUser("myUser", "password").ToString()); 
    Console.WriteLine("Authenticating with new password: " + provider.ValidateUser("myUser", newPassword).ToString()); 

    Console.ReadLine(); 
} 

E l'app.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <connectionStrings> 
     <add name="MyConnectionString" connectionString="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
    <system.web> 
     <membership defaultProvider="MyMembershipProvider"> 
      <providers> 
       <clear /> 
       <add name="MyMembershipProvider" 
        type="System.Web.Security.SqlMembershipProvider" 
        connectionStringName="MyConnectionString" 
        applicationName="MyApplication" 
        minRequiredPasswordLength="5" 
        minRequiredNonalphanumericCharacters="0" 
        requiresQuestionAndAnswer="false" /> 
      </providers> 
     </membership> 
    </system.web> 
</configuration> 
1

metodo sporco rapida

Public Shared Function GetSaltKey() As String 
      Dim saltBytes() As Byte 
      Dim minSaltSize As Integer = 4 
      Dim maxSaltSize As Integer = 8 

      ' Generate a random number for the size of the salt. 
      Dim random As Random 
      random = New Random() 

      Dim saltSize As Integer 
      saltSize = random.Next(minSaltSize, maxSaltSize) 

      ' Allocate a byte array, which will hold the salt. 
      saltBytes = New Byte(saltSize - 1) {} 

      ' Initialize a random number generator. 
      Dim rng As RNGCryptoServiceProvider 
      rng = New RNGCryptoServiceProvider() 

      ' Fill the salt with cryptographically strong byte values. 
      rng.GetNonZeroBytes(saltBytes) 

      ' Convert plain text into a byte array. 
      Return Convert.ToBase64String(saltBytes) 
     End Function 

     Public Shared Function ComputeHash(ByVal password As String, ByVal salt As String) As String 

      Return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(salt & password, _ 
       System.Web.Configuration.FormsAuthPasswordFormat.SHA1.ToString) 
     End Function 

Anche se, lo spazio dei nomi adesione è roba costruito anche per questo, come affermato da Forgotten virgola

+0

Bel metodo ma non uguale all'asp standard.il provider di appartenenza alla rete sta usando - dopo aver impostato una nuova password con questo metodo l'utente non può più effettuare il login. Grazie comunque :) – Anheledir

+1

Sto usando questo codice con il provider di appartenenza di asp.net su un sito di produzione (uno vecchio), ricalcoli la chiave hash e salt e confronti su ogni autenticazione, da cui viene derivata la sicurezza. Non essere schizzinoso, ma la tua domanda ha solo chiesto come calcolare il sale e ha la chiave manualmente. –

1

E 'passato un po' di tempo da quando ho armeggiato con ASP .Net membership, ma ricorda di occuparsi di qualcosa di un po 'correlato ad esso (necessario per personalizzare le cose a causa di un database esistente di utenti). In questo modo ho annullato i metodi (l'utente esistente db aveva md5 hash pwds).

Così nella stessa "linea di pensiero":

espongono l'API di appartenenza attraverso un servizio web che la vostra applicazione desktop può fare riferimento. In questo modo, non stai "ricreando" le cose, le stai riutilizzando. Non devi sovrascrivere nulla, stai solo esponendo i metodi esistenti tramite un servizio Web per la tua app desktop.

Va da sé che si avrebbe dovuto garantire questo endpoint ....

Se quanto sopra è troppo impreciso per il vostro gusto, ecco un link al forum di asp.net per quanto riguarda alcuni tentativi di ricreare l'hashing .... non posso confermare la precisione, ma dovrebbe essere facile da verificare il lavoro svolto:

http://forums.asp.net/p/1336657/2899172.aspx

+0

Grazie per l'idea del tuo servizio web. Hai ragione, in condizioni normali renderei l'intera Membership-Thing disponibile tramite un servizio. Purtroppo le policy aziendali non consentono questo tipo di servizio web :( – Anheledir

15

ho usato riflettore di dare un'occhiata a quei metodi di .NET Framework-sta usando interno. Forse ci sono metodi pubblici disponibili per questo ma non li ho trovati - se sai come interrogare quei metodi interni come utente per favore lascia un commento! :)

Ecco il codice sorgente semplificato senza condizioni inutili, perché voglio solo per codificare la password come SHA1-Hash:

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

private string EncodePassword(string pass, string salt) { 
    byte[] bytes = Encoding.Unicode.GetBytes(pass); 
    byte[] src = Convert.FromBase64String(salt); 
    byte[] dst = new byte[src.Length + bytes.Length]; 
    byte[] inArray = null; 
    Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 
    inArray = algorithm.ComputeHash(dst); 
    return Convert.ToBase64String(inArray); 
} 
+8

non è necessario utilizzare Reflector, la fonte per i provider predefiniti è prontamente disponibile - http://download.microsoft.com/download/a/b/3 /ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi Dai un'occhiata al metodo EncodePassword di SqlMembershipProvider per l'implementazione, che utilizza l'algoritmo hash predefinito, a meno che non venga specificato uno per il MembershipProvider. IIRC, il valore predefinito è SHA-1 –