SQLMembershipProvider: Comparing Hashed Passwords

N

nigeaman

Hi

I am using the SQLMembershipProvider (SQL Server 2000) in ASP.NET 2.0 for
forms authentication using a hashed password format.

I am trying to compare a password the users enters with a list of old
passwords the user has set and then restrict users entering the same password
when they attempt to change their password.

I have created the new audit table to store a copy of the passwords and salt
values from the aspnet_membership table but cannot hash a password entered by
the user to match the password in the database.

I have a password in clear text and the encrypted salt value retreived from
the aspnet_membership table. What actions do I need to perform on both to get
the encrypted password result that is stored in the aspnet_membership table ?

Thanks in advance
Nige
 
L

Luke Zhang [MSFT]

Hello,

Normally, HashResult = HashString(PasswordSalt + Password);

byte[] HashString(string s)
{
....
byte[] data = new byte[DATA_SIZE];
byte[] result;

SHA1 sha = new SHA1CryptoServiceProvider();
result = sha.ComputeHash(data);

}

Hope this help,


Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
N

nigeaman

Hi Luke,

What field is used to create the Password Salt stored in the
aspnet_membership table ? I have tried hashing the UserName and UserID
separately using the function below but this still does not match the
PasswordSalt field contained against a specific user in the aspnet_membership
table.

Dim hashedtext As String = Convert.ToBase64String(HashString(PasswordSalt +
newPassword))

Private Function HashString(ByVal s As String) As Byte()

Dim ue As New System.Text.UnicodeEncoding()
Dim ueString As Byte() = ue.GetBytes(s)
Dim RetVal As Byte() = Nothing

Dim sha As System.Security.Cryptography.SHA1 = New
System.Security.Cryptography.SHA1CryptoServiceProvider()
RetVal = sha.ComputeHash(ueString)

Return RetVal

End Function

Thanks
Nigel
 
D

Dominick Baier [DevelopMentor]

Hi,

the password salt is randomly generated.

If you want to know what is really going on - grab a copy of reflector and
examine SqlMembershipProvider.ValidateUser
there you'll find the logic you are trying to rebuild.

Another approach would be to handle MembershipProvider.ValidatingPassword
- the gets called by CreateUserWizard, ChangePassword and PasswordRecovery -

this gives you the chance to store the password in a history/check them and
cancel the provider operation
..

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
Hi Luke,

What field is used to create the Password Salt stored in the
aspnet_membership table ? I have tried hashing the UserName and UserID
separately using the function below but this still does not match the
PasswordSalt field contained against a specific user in the
aspnet_membership table.

Dim hashedtext As String =
Convert.ToBase64String(HashString(PasswordSalt + newPassword))

Private Function HashString(ByVal s As String) As Byte()

Dim ue As New System.Text.UnicodeEncoding()
Dim ueString As Byte() = ue.GetBytes(s)
Dim RetVal As Byte() = Nothing
Dim sha As System.Security.Cryptography.SHA1 = New
System.Security.Cryptography.SHA1CryptoServiceProvider()
RetVal = sha.ComputeHash(ueString)
Return RetVal

End Function

Thanks Nigel

Luke Zhang said:
Hello,

Normally, HashResult = HashString(PasswordSalt + Password);

byte[] HashString(string s)
{
....
byte[] data = new byte[DATA_SIZE];
byte[] result;
SHA1 sha = new SHA1CryptoServiceProvider(); result =
sha.ComputeHash(data);

}

Hope this help,

Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.
 
N

nigeaman

Hi Luke,

FYI: I have also tried adding the hashed PasswordSalt for a specific user
stored in the database to the clear text Password the users enters. See code
in my previous message. I have also tried using MD5 encryption, but still
cannot match the password stored in the database.

Dim passwordsalt As String = "lV8UArBDHMgv/Ts1IuLXyA=="

Dim md5Hasher As New
System.Security.Cryptography.MD5CryptoServiceProvider()

Dim hashedBytes As Byte()
Dim encoder As New UTF8Encoding()

'hashedBytes =
md5Hasher.ComputeHash(encoder.GetBytes(passwordsalt + newPassword))
hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(username))

Dim hashedText As String = Convert.ToBase64String(hashedBytes)

Thnaks
Nigel

nigeaman said:
Hi Luke,

What field is used to create the Password Salt stored in the
aspnet_membership table ? I have tried hashing the UserName and UserID
separately using the function below but this still does not match the
PasswordSalt field contained against a specific user in the aspnet_membership
table.

Dim hashedtext As String = Convert.ToBase64String(HashString(PasswordSalt +
newPassword))

Private Function HashString(ByVal s As String) As Byte()

Dim ue As New System.Text.UnicodeEncoding()
Dim ueString As Byte() = ue.GetBytes(s)
Dim RetVal As Byte() = Nothing

Dim sha As System.Security.Cryptography.SHA1 = New
System.Security.Cryptography.SHA1CryptoServiceProvider()
RetVal = sha.ComputeHash(ueString)

Return RetVal

End Function

Thanks
Nigel


Luke Zhang said:
Hello,

Normally, HashResult = HashString(PasswordSalt + Password);

byte[] HashString(string s)
{
....
byte[] data = new byte[DATA_SIZE];
byte[] result;

SHA1 sha = new SHA1CryptoServiceProvider();
result = sha.ComputeHash(data);

}

Hope this help,


Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
N

nigeaman

Hi Dominick

Thanks for the tip. Tried downloading Reflector from
http://www.aisto.com/roeder/dotnet/ but the link is broken . Do you have a
copy or no another site I can download this tool from.

Many Thanks
Nigel

Dominick Baier said:
Hi,

the password salt is randomly generated.

If you want to know what is really going on - grab a copy of reflector and
examine SqlMembershipProvider.ValidateUser
there you'll find the logic you are trying to rebuild.

Another approach would be to handle MembershipProvider.ValidatingPassword
- the gets called by CreateUserWizard, ChangePassword and PasswordRecovery -

this gives you the chance to store the password in a history/check them and
cancel the provider operation
..

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
Hi Luke,

What field is used to create the Password Salt stored in the
aspnet_membership table ? I have tried hashing the UserName and UserID
separately using the function below but this still does not match the
PasswordSalt field contained against a specific user in the
aspnet_membership table.

Dim hashedtext As String =
Convert.ToBase64String(HashString(PasswordSalt + newPassword))

Private Function HashString(ByVal s As String) As Byte()

Dim ue As New System.Text.UnicodeEncoding()
Dim ueString As Byte() = ue.GetBytes(s)
Dim RetVal As Byte() = Nothing
Dim sha As System.Security.Cryptography.SHA1 = New
System.Security.Cryptography.SHA1CryptoServiceProvider()
RetVal = sha.ComputeHash(ueString)
Return RetVal

End Function

Thanks Nigel

Luke Zhang said:
Hello,

Normally, HashResult = HashString(PasswordSalt + Password);

byte[] HashString(string s)
{
....
byte[] data = new byte[DATA_SIZE];
byte[] result;
SHA1 sha = new SHA1CryptoServiceProvider(); result =
sha.ComputeHash(data);

}

Hope this help,

Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
N

nigeaman

Managed to download Reflector - fantastic tool. Thanks for this pointer
Dominick.

This is the code create a hashed password:

Friend Function EncodePassword(ByVal pass As String, ByVal salt As
String) As String
Dim buffer1 As Byte() = Encoding.Unicode.GetBytes(pass)
Dim buffer2 As Byte() = Convert.FromBase64String(salt)
Dim buffer3 As Byte() = New Byte((buffer2.Length +
buffer1.Length) - 1) {}
Dim buffer4 As Byte() = Nothing
Buffer.BlockCopy(buffer2, 0, buffer3, 0, buffer2.Length)
Buffer.BlockCopy(buffer1, 0, buffer3, buffer2.Length,
buffer1.Length)
Dim algorithm1 As System.Security.Cryptography.HashAlgorithm =
System.Security.Cryptography.HashAlgorithm.Create(Membership.HashAlgorithmType)
If algorithm1 Is Nothing Then
Throw New Exception("Error creating hash algorithm type:
SHA1")
End If
buffer4 = algorithm1.ComputeHash(buffer3)
Return Convert.ToBase64String(buffer4)
End Function


nigeaman said:
Hi Dominick

Thanks for the tip. Tried downloading Reflector from
http://www.aisto.com/roeder/dotnet/ but the link is broken . Do you have a
copy or no another site I can download this tool from.

Many Thanks
Nigel

Dominick Baier said:
Hi,

the password salt is randomly generated.

If you want to know what is really going on - grab a copy of reflector and
examine SqlMembershipProvider.ValidateUser
there you'll find the logic you are trying to rebuild.

Another approach would be to handle MembershipProvider.ValidatingPassword
- the gets called by CreateUserWizard, ChangePassword and PasswordRecovery -

this gives you the chance to store the password in a history/check them and
cancel the provider operation
..

---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
Hi Luke,

What field is used to create the Password Salt stored in the
aspnet_membership table ? I have tried hashing the UserName and UserID
separately using the function below but this still does not match the
PasswordSalt field contained against a specific user in the
aspnet_membership table.

Dim hashedtext As String =
Convert.ToBase64String(HashString(PasswordSalt + newPassword))

Private Function HashString(ByVal s As String) As Byte()

Dim ue As New System.Text.UnicodeEncoding()
Dim ueString As Byte() = ue.GetBytes(s)
Dim RetVal As Byte() = Nothing
Dim sha As System.Security.Cryptography.SHA1 = New
System.Security.Cryptography.SHA1CryptoServiceProvider()
RetVal = sha.ComputeHash(ueString)
Return RetVal

End Function

Thanks Nigel

:

Hello,

Normally, HashResult = HashString(PasswordSalt + Password);

byte[] HashString(string s)
{
....
byte[] data = new byte[DATA_SIZE];
byte[] result;
SHA1 sha = new SHA1CryptoServiceProvider(); result =
sha.ComputeHash(data);

}

Hope this help,

Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
L

Luke Zhang [MSFT]

Thank Dominick Baier for providing the informaiton about reflector, it can
better help us understand the problem. Actually, the underlying arithmetic
is not public (even we can know some from reflector) and the password salt
is randomly generated. So the best solution for this issue, is to generate
a customized MembershipProvider, record the password history and encrypt
the password by your self.


Luke Zhang
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top