How to create a asp.net membership provider hashed password manually?
I used reflector to take a look at those methods the .NET-Framework is using internal. Maybe there are public methods available for this but I did not find them - if you know how to query those internal methods as a user please left a comment! :)
Here is the simplified source-code without unnecessary conditions because I only want to encode the password as a 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);}
You can absolutely use System.Web.Security
within a console or winforms app.
Here's a simple console application:
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", "user@example.com", 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();}
And the 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>
Quick dirty method
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
Although, the membership namespace has stuff built in for this as well, as stated by Forgotten Semicolon