2011-01-23 49 views
1

我有一个关于盐的问题。例如,在我们 数据库中的记录,看起来像这样:如何使用哈希算法验证明文密码?

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

我试图验证此密码,但我使用的方法是行不通的。

这是方法:

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); 
} 

我将它传递这样的:

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

什么回来看起来不象在数据库中的密码。

我想知道如果还有别的东西我应该对盐做?是 什么是存储在数据库中,我应该传递给EncodePassword方法,或者是 那里有一个步骤,我应该在将它作为 参数传递之前解码它?

我只是不知道为什么我得到一个密码不匹配。根据我工作的站点的web.config,它是passwordFormat =“Hashed”,并且DB中的PasswordFormat列表示“1”,所以我知道它是SHA1。

你有什么想法,为什么我没有得到正确的匹配或如何得到进一步沿着计算出来(是的,我有正确的密码。)

编辑:

我曾尝试以下方法更新:

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); 
} 

针对我目前的DB数据,它仍然是不匹配的。例如,我得到 以下结果:

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


encodedPasswordResults = "DWZ6XRtVMy4l+XSUOKoX8usUOJI=" 

有没有什么办法,有人可以在自己的环境中进行测试,看看为什么我收到这种不同的结果?

+0

你不应该*解密*密码。将输入密码的散列/腌制值与存储的散列/腌制值进行比较。 – 2011-01-23 05:16:49

+0

谢谢科迪 - 同意。那正是我想要做的 - 只是没有把这个问题描述得很好。尝试验证明文密码。 – 2011-01-23 06:48:40

+0

您确定它只是SHA1的一次迭代吗?在密码散列函数中迭代散列数千次是很常见的。 salt和密码之间是否应该有分隔符? – caf 2011-01-24 02:32:42

回答

0

SHA1不容易解密,这是它用来存储密码的原因之一。你为什么试图解密密码?

1

如果你正在传递salt,就像它存储在数据库中一样,那么你正在处理一个Base-64编码的字符串。要将其转换为byte[]阵列,您应该使用Convert.FromBase64String而不是Unicode.GetBytes。沿着这些路线的东西:

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); 
} 

顺便说一句,虽然你的问题多次提及解密密码,在我看来,就好像你只是想验证对存储的哈希明文密码。如果是这种情况,那么上面的代码应该没问题。

如果你真的试图解密存储的散列,那么不要打扰!散列不是密码的加密版本,因此解密是不可能的。