1

I have a question about salts. For example, there is a record in our database that looks like this:

Password: YUphoRF70vJEPAOjMmc/9n47hyQ= 
Password Format: 1 
Password Salt: Vx37L8ItQo3rJzx5gRCxTw==

I am trying to verify this password, but the method I am using isn't working.

This is the method:

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

And I pass it like this:

string encodedPasswd = Cryptography.EncodePassword(ClearTxtPassword, DbPasswordSalt);

What comes back does not look like the password in the database.

I am wondering if there is something else I should be doing to the salt? Is what is stored in the DB what I should be passing to the EncodePassword method or is there a step in between in which I should be decoding it prior to passing it as a parameter?

I am just not sure why I am getting a password mismatch. According to the web.config of the site I am working on, it is passwordFormat="Hashed" and the PasswordFormat column in the DB says "1" so I know it is SHA1.

Do you have any ideas why I am not getting the right match or how to get further along in figuring it out?(And yes, I have the right password.)

EDIT:

I have tried the following updated method:

public static 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];
    Buffer.BlockCopy(src, 0, dst, 0, src.Length);
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
    byte[] inArray = algorithm.ComputeHash(dst);
    return Convert.ToBase64String(inArray);
}

Against my current DB data and it still isn't matching up. For example, I am getting the following results:

passwordText = "administrator"
passwordformat: 1 / SHA1
passwordSaltInDb: "zVhahfmXj9MrOQySyPQ1Qw=="
passwordInDb = "YZ5xRJkNG9erGStAkWJA3hID9vE="


encodedPasswordResults = "DWZ6XRtVMy4l+XSUOKoX8usUOJI="

Is there any way that somebody could test on in their own environment to see why I am getting such different results?

5
  • You should never decrypt passwords. Compare the hashed/salted value of the input password to the stored hashed/salted value. Commented Jan 23, 2011 at 5:16
  • Thanks Cody - agreed. That is what I was trying to do - just didn't describe the problem all that well. Trying to validate a cleartext password. Commented Jan 23, 2011 at 6:48
  • Are you sure that it is only a single iteration of SHA1? It is common in password hashing functions to iterate the hash thousands of times. Should there be a delimiter character between the salt and the password? Commented Jan 24, 2011 at 2:32
  • Is this still open? It looks like you have to find out how the salted passwords were originally created, and then copy this method. There is not much point in guessing the right algorithm. Commented Aug 22, 2011 at 20:36
  • There's a virtually infinite number of subtle variations on how the salt could be applied and how parameters could be encoded. I don't think you're going to make this work without some good documentation on the procedure used. Commented Aug 23, 2011 at 1:16

2 Answers 2

1

If you're passing in the salt exactly as it's stored in the database then you're dealing with a Base-64 encoded string. To convert it to a byte[] array you should use Convert.FromBase64String rather than Unicode.GetBytes. Something along these lines:

public static 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];
    Buffer.BlockCopy(src, 0, dst, 0, src.Length);
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
    byte[] inArray = algorithm.ComputeHash(dst);
    return Convert.ToBase64String(inArray);
}

By the way, although your question repeatedly mentions decrypting the password, it looks to me as if you're simply trying to validate a plaintext password against the stored hash. If that's the case then the above code should be fine.

If you really are trying to decrypt the stored hash then don't bother! The hash is not an encrypted version of the password, so decrypting it is impossible.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks LukeH... yes, you were right. I was talking about cleartext password validating - that is my bad. I have tried your updated method and posted my update - it's still not working. Any chance you can test this? Any further thoughts?
Regarding your update... I've tried running the code with your example data -- "administrator" and "zVhahfmXj9MrOQySyPQ1Qw==" -- and can't match either the passwordInDb or encodedPasswordResults from your example. Are you sure that the plaintext password should be "administrator"?
0

SHA1 isn't readily decryptable, which is one of the reasons it's used to store passwords. Why are you trying to decrypt the passwords?

1 Comment

Yes, thanks Rob. I was using the wrong wording as LukeH has pointed out. I am trying to "validate" a cleartext password. Please see my edit - can you offer further advice?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.