我们使用以下代码在 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);
}
传入的 key 是一个 256 位的 base 64 编码字符串。有人问我们是否应该使用 HMACSHA256、HMACSHA384 或 HMACSHA512 来散列该值。
- 与 HMACSHA256 相比,使用 HMACSHA512 有哪些优势?
- 它是否更安全?
- 使用更长的 key 是否会对性能产生显着影响?
作为旁注;如果我使用 HMACSHA512,我传递给构造函数的 decodedKey
值是否需要是 512 位 key ?
最佳答案
TL;DR:使用 HMAC-SHA512 以获得最佳速度、安全性和 OK 兼容性。 HMAC-SHA256 也非常安全,可用于 32 位运算的 CPU。此外,它在许多最新的 CPU 上得到了加速。
要了解哈希方法本身的强度,请查看 keylength.com website .你会发现即使是 SHA-256 也有相当大的安全余量。
此外,HMAC 算法几乎不会注意到对底层哈希算法的攻击。 HMAC 不受生日问题的影响,生日问题将 key 强度减半为哈希输出的一半。它并不适用,因为对手没有持有 key ,因此不能尝试制造冲突。这就是为什么即使 HMAC-SHA1 也非常安全。
现在散列的速度取决于执行环境。但总的来说,您可以做出以下假设:
- SHA-1 通常比同一平台上的任何 SHA-2 实现更快;
- SHA-512 在 64 位机器上比 SHA-256 更快(因为它们在内部使用 64 位算法);
- SHA-256 在 8、16 和 32 位机器上比 SHA-512 更快。
如果您预计会出现兼容性问题,请使用 SHA-1。否则你也可以选择 SHA-512(并将结果削减到合理的位数)。 SHA-512 的内部状态和更高的安全性可能略有优势。由于算法的一般问题,我遇到了客户不接受任何形式的 SHA-1 的问题;换句话说,它一般不安全的事实可能会阻碍接受。
请注意,SHA-384 和不太为人所知的 SHA-512/256 和 SHA-512/224 哈希方法是 SHA-512 的一种特殊形式,被切割成 384、256 和 224 位输出。所以这些算法的速度是相同的。除了输出大小之外的唯一区别是这些特殊形式在内部使用不同的初始值。否则,切割成 384 位的 SHA-512 与 SHA-512/384 一样安全和快速。但是,您应该使用 SHA-384 来保持兼容性 - 如果您需要特定的输出大小。
SHA-384 和 SHA-512/256 以及 SHA-512/224 使用不同的初始值,因此它们中的任何一个的输出都不同于 SHA-512 和彼此;称为域分离的功能。域分离使得无法使用攻击或(部分)预测其他相关哈希函数的哈希结果。
输入 key 的大小不依赖于底层哈希函数。 key 首先进行异或屏蔽,然后由底层哈希函数进行哈希处理;哈希算法几乎可以将无限量的数据作为输入。
建议使用的 key 大小至少为所用散列方法的大小,否则可能会降低 HMAC 方法提供的安全边际。如果 key 大小强制哈希算法对多个 block 进行哈希处理,则可能会有轻微的性能损失。
您还可以使用(即将推出的)SHA-3 标准,因为它是安全的。不过,HMAC-SHA-3 目前并没有太大意义。 HMAC 实际上对 SHA-3 (Keccak) 来说有点矫枉过正;即使没有 HMAC 构造,SHA-3 也应该是安全的。到目前为止,KMAC 已被标准化为 SHA-3 的 MAC 结构。
SHA-2 结构在 SHA-3 竞赛期间表现出相当好的抵抗密码分析的能力,这有点令人惊讶。因此,没有迫切需要升级到 KMAC/SHA-3。
关于c# - HMACSHA256 和 HMACSHA512 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18080445/