SHA256哈希计算

3

我需要为我的雇主向Web应用程序的客户提供某些文件的校验和。

我想向用户展示他们客户端工具可能生成的哈希值,因此我一直在比较在线哈希工具。我的问题是关于它们的哈希形式,因为它们不同,很奇怪。

经过快速搜索,我测试了5个:

  1. http://www.convertstring.com/Hash/SHA256
  2. http://www.freeformatter.com/sha256-generator.html#ad-output
  3. http://online-encoder.com/sha256-encoder-decoder.html
  4. http://www.xorbin.com/tools/sha256-hash-calculator
  5. http://www.everpassword.com/sha-256-generator
输入值“test”(后面没有“enter”),所有5个工具都给出了相同的SHA256结果。然而,这里开始有点奇怪,当我输入值“test [enter] test”(即两行)时,在线工具1、2和3给出相同的SHA256哈希值,而网站4和5给出不同的哈希值(因此1,2和3相等,4和5相等)。这很可能与工具或底层代码处理\r\n的方式有关,至少我是这样认为的。
巧合的是,网站1、2和3向我呈现了与我的C#代码相同的哈希值:
    var sha256Now = ComputeHash(Encoding.UTF8.GetBytes("test\r\ntest"), new SHA256CryptoServiceProvider());

    private static string ComputeHash(byte[] inputBytes, HashAlgorithm algorithm)
    {
        var hashedBytes = algorithm.ComputeHash(inputBytes);
        return BitConverter.ToString(hashedBytes);
    }

问题是:哪些网站是“正确的”?
有没有办法知道哈希是否符合标准?
更新1:将编码更改为UTF8。这对创建输出哈希没有影响。感谢@Hans。(因为我的Encoding.Default可能是Encoding.UTF8)
更新2:也许我应该稍微扩展一下问题,因为它可能没有解释清楚,抱歉。我想问的更多是一个可用性问题而不是技术问题;我应该提供所有具有不同行结尾的哈希吗?还是应该坚持一个?客户可能会打电话给我的公司,担心他们的文件以某种方式被更改了,如果他们有不同的计算哈希的方法。通常如何解决这个问题?

2
你认为哪种行尾是正确的?从\r、\n或\r\n中选择。顺便担心一下文本编码。 - Hans Passant
@Hans,我不知道你想告诉我什么。 - Gerben Rampaart
哈希算法作用于字节。有很多不同的方法可以将字符串转换为字节,它们都是“正确”的。如果你因为某些原因喜欢Encoding.Default,那么当你的代码在另一台具有不同默认设置的机器上运行时,你会后悔的。还有一百种选择。只要你必须选择一个不依赖于机器设置的编码方式,那么你选择Encoding.UTF8就不会出错。 - Hans Passant
1
那我就使用UTF8编码。尤其是因为你保证我不会被解雇。 - Gerben Rampaart
1个回答

2

所有这些网站都返回有效值。

网站4和5使用\n作为换行符。


编辑

我看到您在代码示例中添加了Encoding.Default.GetBytes

这很有趣,因为你会发现在计算哈希之前需要进行一些字符串转字节数组的转换。换行符(\n\r\n)以及文本编码都是不同的方式来解释您的字符串以获取不同的字节值。

一旦你有了相同的输入字节,所有哈希结果将是相同的。


编辑2:

如果您直接处理字节,则只需使用这些字节计算哈希值。不要尝试提供不同的哈希值;哈希必须只返回一个值。如果您的客户端具有与您不同的哈希值,则他们操作错误

话虽如此,我确信这种情况永远不会发生,因为没有任何方法会误解一个字节数组。


我明白。但是向客户展示哈希值会让哈希值在他们眼中变成“正确”或“错误”,你不觉得吗?你认为我应该同时使用\r和\r\n来展示哈希值吗?我没问题,但我不确定这是否是向客户展示哈希值的正确方式。 - Gerben Rampaart
如果你的输入是“文件”(如你问题中所指定),那么你甚至不需要处理换行或文本编码。你只需使用流读取文件并将其传递给哈希算法;你不必解释文本。 - ken2k
你说得对,那确实是我的情况,我重新编写了代码示例以更好地解释我与在线工具的交互。但你说得对,我有一个byte[]输入。这并不影响我从迄今为止测试过的文件中获取的哈希值。我可以使用File.ReadAllBytes(path);读取byte[]并计算,也可以使用File.ReadAllText(path);然后使用Encoding.UTF8.GetBytes()。两者都具有相同的SHA256结果。 - Gerben Rampaart
等等,我开始明白你在说什么了(终于),所以在线工具,由于它们是基于字符串的,实际上会因为平台(行结尾)而有所不同。如果我有一种方法可以将这些在线工具提供给一个byte[],那么我们最终都会得到相同的哈希值? - Gerben Rampaart
@GerbenRampaart 是的,完全正确。 - ken2k

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