Thursday, November 18, 2010

Compare string with Aspnet_Membership password

Small time ago I had a particular problem, I need to compare a password written by a user in a client WinForms software with an Asp.net managed password (stored in Aspnet_Membership table).

The main problem is that the Asp.net password is encrypted in db and it's not possible to decrypt. The only way to solve the problem is to encrypt given password in the same way as Asp.net and then compare password hashes. To do it, "Salt" is needed: the value of PasswordSalt column in Aspnet_Membership.

Here the code (I'm sorry but i haven't enought time to colorize the code :D ):

VB.Net


Public Function Compare(ByVal password As String, ByVal aspnetSalt As String, ByVal aspnetPassword As String) As Boolean
    Dim isEqual As Boolean = False
    If aspnetPassword = GenerateHash(password, aspnetSalt) Then
        isEqual = True
    End If
    Return isEqual
End Function

Private Function GenerateHash(ByVal pwd As String, ByVal salt As String) As String
    Dim p1 As Byte() = Convert.FromBase64String(salt)
    Return GenerateHash(pwd, p1)
End Function

Private Function GenerateHash(ByVal pwd As String, ByVal saltAsByteArray As Byte()) As String
    Dim sha As New System.Security.Cryptography.SHA1CryptoServiceProvider()
    Dim p1 As Byte() = saltAsByteArray
    Dim p2 As Byte() = System.Text.Encoding.Unicode.GetBytes(pwd)
    Dim data() As Byte = New Byte(((p1.Length + p2.Length)) - 1) {}
    p1.CopyTo(data, 0)
    p2.CopyTo(data, p1.Length)
    Dim result As Byte() = sha.ComputeHash(data)
    Dim rtn As String = Convert.ToBase64String(result)
    Return rtn
End Function


C#

public boolean Compare (string password, string aspnetSalt, string aspnetPassword)
{
    boolean isEqual = False
    If (aspnetPassword = GenerateHash(password, aspnetSalt))
    {
        isEqual = True
    }
    return isEqual
}

private string GenerateHash(string pwd, string saltAsBase64)
{
    byte[] p1 = Convert.FromBase64String(saltAsBase64);
    return GenerateHash(pwd, p1);
}

private string GenerateHash(string pwd, byte[] saltAsByteArray)
{
    System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();

    byte[] p1 = saltAsByteArray;
    byte[] p2 = System.Text.Encoding.Unicode.GetBytes(pwd);

    byte[] data = new byte[p1.Length + p2.Length];

    p1.CopyTo(data, 0);
    p2.CopyTo(data, p1.Length);

    byte[] result = sha.ComputeHash(data);

    string res = Convert.ToBase64String(result);
    return res;
}

3 comments:

Nguyen Van Minh said...

Thank you so much

Anonymous said...

And if I want detect if password is correct from a not .NET procedure how can I do ?

Davide Benvegnù said...

[quote]
And if I want detect if password is correct from a not .NET procedure how can I do ?
[/quote]
What did you mean with "from a not .NET procedure"?