gpt4 book ai didi

c# - C# 中的哈希摘要/数组比较

转载 作者:太空宇宙 更新时间:2023-11-03 22:17:23 25 4
gpt4 key购买 nike

我正在编写一个需要验证 HMAC-SHA256 校验和的应用程序。我目前的代码看起来像这样:

    static bool VerifyIntegrity(string secret, string checksum, string data)
{
// Verify HMAC-SHA256 Checksum
byte[] key = System.Text.Encoding.UTF8.GetBytes(secret);
byte[] value = System.Text.Encoding.UTF8.GetBytes(data);
byte[] checksum_bytes = System.Text.Encoding.UTF8.GetBytes(checksum);
using (var hmac = new HMACSHA256(key))
{
byte[] expected_bytes = hmac.ComputeHash(value);
return checksum_bytes.SequenceEqual(expected_bytes);
}
}

我知道这很容易受到 timing 的影响attacks .

标准库中有消息摘要比较函数吗?我意识到我可以编写自己的时间硬化比较方法,但我必须相信这已经在其他地方实现了。

最佳答案

编辑:原始答案在下面 - IMO 仍然值得一读,但关于定时攻击......

您引用的页面提供了一些关于编译器优化的有趣观点。假设您知道两个字节数组的长度相同(假设校验和的大小 不是特别机密,如果长度不同您可以立即返回)您可以尝试 像这样:

public static bool CompareArraysExhaustively(byte[] first, byte[] second)
{
if (first.Length != second.Length)
{
return false;
}
bool ret = true;
for (int i = 0; i < first.Length; i++)
{
ret = ret & (first[i] == second[i]);
}
return ret;
}

现在所有输入仍然不会花费相同的时间 - 例如,如果两个数组都在 L1 缓存中,它可能比必须从主内存中获取更快。但是,从安全角度来看,我怀疑这不太可能导致重大问题。

这样可以吗?谁知道。不同的处理器和不同版本的 CLR 可能需要不同的时间来处理 &。操作取决于两个操作数。基本上这与您引用的页面的结论相同 - 它可能与我们以可移植方式获得的一样好,但它需要在您尝试运行的每个平台上进行验证。

至少上面的代码只用了比较简单的操作。我个人会避免在这里使用 LINQ 操作,因为在某些情况下可能会进行偷偷摸摸的优化。我认为在这种情况下不会 - 或者他们很容易打败 - 但你至少必须考虑他们。对于上面的代码,源代码和 IL 之间至少存在相当密切的关系——“只”留下 JIT 编译器和处理器优化需要担心:)


原始答案

这有一个重要的问题:为了提供校验和,您必须有一个字符串,其 UTF-8 编码形式与校验和相同。有很多字节序列根本不代表 UTF-8 编码的文本。基本上,尝试使用 UTF-8 将任意二进制数据编码为文本是一个坏主意。

另一方面,Base64 基本上是设计的:

static bool VerifyIntegrity(string secret, string checksum, string data)
{
// Verify HMAC-SHA256 Checksum
byte[] key = Encoding.UTF8.GetBytes(secret);
byte[] value = Encoding.UTF8.GetBytes(data);
byte[] checksumBytes = Convert.FromBase64String(checksum);
using (var hmac = new HMACSHA256(key))
{
byte[] expectedBytes = hmac.ComputeHash(value);
return checksumBytes.SequenceEqual(expectedBytes);
}
}

另一方面,不是在字节数组上使用 SequenceEqual,而是可以对实际哈希进行 Base64 编码,然后查看它是否匹配:

static bool VerifyIntegrity(string secret, string checksum, string data)
{
// Verify HMAC-SHA256 Checksum
byte[] key = Encoding.UTF8.GetBytes(secret);
byte[] value = Encoding.UTF8.GetBytes(data);
using (var hmac = new HMACSHA256(key))
{
return checksum == Convert.ToBase64String(hmac.ComputeHash(value));
}
}

我不知道框架内有什么更好的。写一个专门的 SequenceEqual 不会太难数组(或一般 ICollection<T> 实现)的运算符首先检查相等的长度...但考虑到散列很短,我不会担心这一点。

关于c# - C# 中的哈希摘要/数组比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4571691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com