C#中使用盐值的MD5哈希函数将密码保存到数据库中

18

请问有没有一些简单的MD5密码哈希算法,但带以增加可靠性。

现在我有这个:

private static string GenerateHash(string value)
{
    var data = System.Text.Encoding.ASCII.GetBytes(value);
    data = System.Security.Cryptography.MD5.Create().ComputeHash(data);
    return Convert.ToBase64String(data);
}

5
为什么要使用像MD5这样的破损哈希函数?至少应该使用像SHA-256这样的东西。 - Greg Beech
6
为什么不使用MD5?合理使用盐可以缓解由于MD5缺乏碰撞抗性而导致的漏洞,不是吗? - Eric Lippert
1
@Greg,请问你能提供一些使用示例吗?如果有必要,可以加盐。 - abatishchev
这并不是碰撞抗性的问题。问题在于它已经存在了足够长的时间,有优化的实现可以快速地强制执行“反向”。 - Joel Coehoorn
1
@Eric - 当然,它在一定程度上减轻了安全问题,但为什么要从不安全的东西开始呢?使用更安全的东西同样容易(即相同的代码,只需更换算法名称)。 - Greg Beech
显示剩余2条评论
3个回答

41
您可以使用 HMACMD5 类:
var hmacMD5 = new HMACMD5(salt);
var saltedHash = hmacMD5.ComputeHash(password);

同时适用于SHA-1、SHA256、SHA384、SHA512和RIPEMD160:

var hmacSHA1 = new HMACSHA1(salt);
var saltedHash = hmacSHA1.ComputeHash(password);

期望使用字节数组传递saltpassword

如果您有字符串,则必须首先将其转换为字节数组:

var salt = System.Text.Encoding.UTF8.GetBytes("my salt");
var password = System.Text.Encoding.UTF8.GetBytes("my password");

1
HMACSHA1构造函数接受的不是盐而是一个密钥作为单个参数。 - abatishchev
4
HMAC通常用于获取消息的密钥哈希。如果您将密钥替换为盐并使用密码替换消息,则可以使用HMAC获取加盐密码的哈希值。 - dtb
有没有解密加盐密码的方法? - Sana Ahmed
@Sana 不,这些是单向哈希函数,无法被反转。只有暴力破解、彩虹表攻击(盐值使其过时)和社交工程等攻击方式才能有效地确定未加密的密码。 - Jacob Stamm

4

除了上面提到的HMACSHA1类之外,如果您只需要一个快速的加盐哈希值,那么您已经完成了95%的工作:

private static string GenerateHash(string value, string salt)
{
    byte[] data = System.Text.Encoding.ASCII.GetBytes(salt + value);
    data = System.Security.Cryptography.MD5.Create().ComputeHash(data);
    return Convert.ToBase64String(data);
}

真正的技巧在于将盐值存储在安全的地方,比如您的machine.config文件中。

时间戳可以作为一个好的盐值吗?或者发现这个事实会危及整个算法? - abatishchev
时间戳不起作用,因为当您验证哈希与新输入时,时间将会不同。 - Fantius
除非您将时间戳与摘要一起存储,否则它可以工作但不太安全。 - Fantius
7
如果您的实现安全性依赖于保密盐值,那么您可能会遇到大麻烦! - LukeH
3
强烈建议使用System.Text.Encoding.UTF8而不是ASCII。 - zanlok
@Juliet,我误点了踩的按钮,很抱歉。我试图撤销它,但是投票已经锁定了。 - Vamsi

1

微软已经为您完成了这项工作,但需要进行一些挖掘。安装Web Service Extensions 3.0,并查看使用Reflector的Microsoft.Web.Services3.Security.Tokens.UsernameToken.ComputePasswordDigest函数。

我想在此处发布该功能的源代码,但不确定是否合法。如果有人能向我保证,我会这样做。


3
我怀疑合法性很大程度上取决于你所在的地方。在某些司法管辖区,甚至查看反编译代码本身都是违法的,更别说将其发布供他人查看了! - LukeH
2
尽管使用Visual Studio 2008在调试时可以查看.NET的源代码,但前提是您首先同意了微软的条款和条件。 - Chris Chilvers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接