【问题标题】:HMAC SHA1 using the same value for key and messageHMAC SHA1 对密钥和消息使用相同的值
【发布时间】:2012-01-19 22:35:06
【问题描述】:
我正在编写一些 C# 安全代码,当我看到它正在使用 HMACSHA1 类时正要替换它。该代码用于散列密码以存储在数据库中。引起我注意的是它使用密码作为 HMAC 密钥,这正是计算哈希的目的。那么将数据用于密钥和您的散列可以吗?这会使安全性更强还是更弱?
伪代码:
string pwd = "My~!Cra2y~P@ssWord1#123$";
using (HMACSHA1 hasher = new HMACSHA1())
{
hasher.Key = encoding.GetBytes(pwd); // using password for the key
return BytesToHex(hasher.ComputeHash(encoding.GetBytes(pwd))); // computing the hash for the password
}
【问题讨论】:
标签:
c#
.net
security
hmacsha1
【解决方案1】:
它的强度与经过两次迭代的未加盐 SHA1 哈希值差不多。即相当弱。
缺少盐允许攻击创建彩虹表,或者简单地同时攻击数据库中的所有密码哈希。
低迭代次数使攻击速度更快,因为攻击者可以简单地尝试更多的候选密码。
您应该添加盐,并使用较慢的散列方法,例如 PBKDF2 和 bcrypt。 .net 类Rfc2898DeriveBytes 实现了 PBKDF2,所以我推荐使用那个。
【解决方案2】:
我不建议将 HMACSHA1 用于数据库密码存储,但是将 Key 设置为与密码相同确实会削弱 Key 在此用途中的有用性。密钥应该是秘密的,用于确定底层散列数据是否已更改。
对于密码,您应该使用 SALT+Password 组合来提高 HASH 算法的安全性。我通常使用用户唯一的SALT,但与密码不同,例如用户号或初始注册IP地址。
另外,请记住,不再推荐将 SHA1 作为哈希算法。
您可以参考MSDN以获得更清晰的理解。
此属性是键控散列算法的键。
基于哈希的消息验证码 (HMAC) 可用于
确定通过不安全通道发送的消息是否已被
篡改,前提是发送者和接收者共享一个秘密
钥匙。发送方计算原始数据的哈希值,然后
将原始数据和 HMAC 作为单个消息发送。这
接收者重新计算接收到的消息的哈希值并检查
计算的哈希值与传输的哈希值匹配。
HMAC 可以与任何迭代加密哈希函数一起使用,例如
作为 MD5 或 SHA-1,与秘密共享密钥结合使用。这
HMAC 的加密强度取决于
底层哈希函数。
对数据或哈希值的任何更改都会导致不匹配,
因为需要知道密钥才能更改消息
并重现正确的哈希值。因此,如果原始和
计算的哈希值匹配,则消息已通过身份验证。