我们使用以下代码针对C#
中的敏感值生成HMac哈希public string GenerateHMac(string key, string message)
{
var decodedKey = Convert.FromBase64String(key);
var hasher = new HMACSHA256(decodedKey);
var messageBytes = Encoding.Default.GetBytes(message);
var hash = hasher.ComputeHash(messageBytes);
return Convert.ToBase64String(hash);
}
传入的密钥是256位base 64编码字符串。我们提出了一个问题,即我们是否应该使用HMACSHA256,HMACSHA384或HMACSHA512对该值进行散列。
作为旁注;如果我使用HMACSHA512,我传递给构造函数的decodedKey
值是否需要是512位密钥?
答案 0 :(得分:21)
TL; DR:使用HMAC-SHA512获得最佳速度,安全性和良好的兼容性。 SHA-256也非常安全,可以在具有32位操作的CPU上使用。
要查看哈希方法本身的强度,请查看keylength.com website。你会发现即使是SHA-256也有相当大的安全边际。
更重要的是,HMAC算法几乎无视对底层哈希算法的攻击。 HMAC不受生日问题的影响,将关键强度减半,使哈希输出减半。它不适用仅仅是因为攻击者不持有密钥,因此不能尝试创建冲突。这就是为什么即使HMAC-SHA1也非常安全。
现在哈希的速度取决于执行环境。但总的来说,你可以做出以下假设:
如果您预计兼容性问题,请使用SHA-1。否则你也可以选择SHA-512(并将结果切换到合理的位数)。 SHA-512的内部状态和更高的安全性可能是一个小优势。由于算法的一般问题,我遇到了不接受任何形式的SHA-1的客户的问题;换句话说,一般不安全的事实可能会妨碍接受。
请注意,SHA-384和不太知名的SHA-512/256和SHA-512/224哈希方法是SHA-512的一种特殊形式,切换为384,256和224位输出。所以这些算法的速度是相同的。除输出大小之外的唯一区别是这些特殊形式在内部使用不同的初始值。否则,SHA-512切割到384位与SHA-512/384一样安全和快速。但是,如果需要特定的输出大小,则应使用SHA-384保持兼容。
SHA-384和SHA-512/256和SHA-512/224使用不同的初始值,因此它们中的任何一个的输出都不同于SHA-512和彼此;称为域分离的功能。域分离使得无法使用攻击或(部分)预测其他相关哈希函数的哈希结果。
输入密钥大小不依赖于底层哈希函数。密钥首先进行XOR掩码,然后通过底层哈希函数进行哈希处理;哈希算法可以将几乎无限量的数据作为输入。
建议使用至少与所使用的哈希方法大小相同的密钥大小,否则可能会降低HMAC方法提供的安全边际。如果密钥大小强制散列算法散列多个块,则可能会有轻微的性能损失。
您也可以使用(即将推出的)SHA-3标准,因为它是安全的。 HMAC-SHA-3目前并没有太多意义。 HMAC实际上对SHA-3(Keccak)来说太过分了;即使没有HMAC结构,SHA-3也应该是安全的。到目前为止, KMAC 已被标准化为SHA-3的MAC结构。
SHA-2构造在某种程度上令人惊讶地显示出在SHA-3竞争期间对密码分析具有相当好的抵抗力。因此没有迫切需要升级到KMAC / SHA-3。
答案 1 :(得分:4)
我认为您不必担心安全性优势,HmacSha1仍然被认为是secure,并且应该将安全性视为相对于密钥长度。 Sha256 vs Sha512的性能将取决于实现,平台等,你必须自己测试一下。您为HMAC提供的密钥长度与散列算法无关,请参阅pseudocode。
答案 2 :(得分:0)
HMAC调用哈希算法两次,而SHA3不需要HMAC构造用于键控哈希,因此可以轻松避免双重调用。 因此,SHA3在性能方面优于HMAC-SHA2,在安全方面优于HMAC-SHA1(两全其美)。