2010-03-30 10 views
12

J'utilise un site Web en tant que frontend et tous les utilisateurs sont authentifiés avec le fournisseur d'adhésion ASP.NET standard. Les mots de passe sont enregistrés "hachés" dans une base de données SQL.Comment créer manuellement un mot de passe hashed pour un fournisseur d'appartenance asp.net?

Maintenant, je veux écrire un client de bureau avec des fonctions administratives. Entre autres choses, il devrait y avoir une méthode pour réinitialiser le mot de passe d'un utilisateur. Je peux accéder à la base de données avec les données d'appartenance enregistrées, mais comment puis-je créer manuellement le mot de passe-sel et -hash? L'utilisation de l'espace de noms System.Web.Membership semble inappropriée. J'ai donc besoin de savoir comment créer manuellement le sel et le hash du nouveau mot de passe.

Les experts intensifient! :)

+2

Pourquoi est-System.Web.Security inapproprié? On dirait que le bon outil pour le travail. –

+0

Je ne peux pas inclure un fournisseur d'appartenances dans une application client-client, en utilisant ma base de données sql, puis-je? Quand c'est possible, vous avez raison et je peux utiliser ces méthodes ... mais comment l'implémenter? – Anheledir

Répondre

13

Vous pouvez absolument utiliser System.Web.Security dans une application console ou WinForms.

Voici une application simple de la 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(); 
} 

Et le 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

méthode sale rapide

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 

Bien que, l'espace de noms de membres a des choses construit pour cela aussi, comme l'a déclaré oublié Semicolon

+0

Belle méthode mais pas la même que l'asp standard.net-member-provider utilise - après avoir défini un nouveau mot de passe avec cette méthode, l'utilisateur ne peut plus se connecter. Merci quand même :) – Anheledir

+1

J'utilise ce code avec le fournisseur d'appartenance asp.net sur un site de production (un ancien), vous recalculez la clé de hachage et de sel et comparez sur chaque authentification, d'où vient la sécurité. Ne pas être difficile, mais votre question a seulement demandé comment calculer le sel et a la clé manuellement. –

1

Cela fait quelque temps que je l'ai bricolé avec ASP L'adhésion .Net, mais n'oubliez pas de traiter avec quelque chose d'un peu lié (nécessaire pour personnaliser les choses en raison d'une base de données existante des utilisateurs). Dans cet effort, j'ai surpassé les méthodes (l'utilisateur existant DB avait md5 hashed pwds).

Ainsi, dans la même « ligne de pensée »:

Expose l'API d'adhésion via un service Web que votre application de bureau peut faire référence. De cette façon, vous n'êtes pas en train de "recréer" des choses, vous les réutilisez. Vous n'avez rien à redéfinir, vous exposez simplement les méthodes existantes via un service Web pour votre application de bureau.

Cela va sans dire que vous auriez à sécuriser ce point final ....

Si ce qui précède est trop peu précis pour votre goût, voici un lien vers les forums asp.net concernant quelques tentatives pour recréer le hachage .... Je ne peux pas confirmer l'exactitude, mais il devrait être facile de le tester:

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

+0

Merci pour votre idée de service web. Vous avez raison, dans des conditions normales, je ferais en sorte que toute l'adhésion soit disponible via un service. Malheureusement, les politiques de l'entreprise ne permettent pas ce type de service web :( – Anheledir

15

J'utilisé réflecteur pour jeter un oeil à ces méthodes le .NET Framework utilise interne. Peut-être qu'il existe des méthodes publiques disponibles pour cela mais je ne les ai pas trouvées - si vous savez comment interroger ces méthodes internes en tant qu'utilisateur s'il vous plaît laissez un commentaire! :)

Voici le code source simplifiée, sans conditions inutiles parce que je ne veux que de coder le mot de passe comme 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

pas besoin d'utiliser Reflector, la source pour les fournisseurs par défaut est facilement disponible - http://download.microsoft.com/download/a/b/3 /ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi Jetez un oeil à la méthode EncodePassword de SqlMembershipProvider pour l'implémentation.Il utilise l'algorithme de hachage par défaut sauf si un est spécifié pour le MembershipProvider.IIRC, la valeur par défaut est SHA-1 –

Questions connexes