6

我得到了这样一段代码:

void SHAPresenter::hashData(QString data)
{
    QCryptographicHash* newHash = new QCryptographicHash(QCryptographicHash::Sha3_224);
    newHash->addData(data.toUtf8());
    QByteArray hashResultByteArray = newHash->result();
    setHashedData(QString(hashResultByteArray.toHex()));
    delete newHash;
}

根据Qt 规范QCryptographicHash::Sha3_224应该“生成一个 SHA3-224 哈希和。在 Qt 5.1 中引入”。我想将该代码的结果与其他来源进行比较,以检查我是否以正确的方式放置数据。我找到了网站:https : //emn178.github.io/online-tools/sha3_224.html 所以我们在这两种情况下都有 SHA3_224。问题是第一个会从“test”生成这样一个字节串:

3be30a9ff64f34a5861116c5198987ad780165f8366e67aff4760b5e

第二个:

3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b

一点都不相似。但也有一个做“Keccak-224”的网站: https ://emn178.github.io/online-tools/keccak_224.html

这里的结果是:

3be30a9ff64f34a5861116c5198987ad780165f8366e67aff4760b5e

我知道 SHA3 是基于 Keccak 的功能 - 但这里有什么问题?这两种实现中的哪一种以适当的方式遵循 NIST FIPS 202,我们如何知道这一点?

4

2 回答 2

2

我现在正在为 Java 编写一个 Keccak 库,所以我有手边的玩具来测试最初的怀疑。

首先做一个简短的总结。Keccak是一个海绵函数,它可以采用许多参数(比特率、容量、域后缀和输出长度)。SHA-3 只是 Keccak 的一个子集,其中这些值已由 NIST(在FIPS PUB 202中)选择和标准化。

在SHA3-224的情况下,参数如下:

bitrate: 1152
capacity: 448
domain suffix: "01"
output length: 224 (hence the name SHA3-224)

需要注意的重要一点是域后缀是一个位串,它在输入消息之后和填充之前附加。域后缀是区分 Keccak 函数的不同应用(如 SHA3、SHAKE、RawSHAKE 等)的可选方式。所有 SHA3 函数都使用“01”作为域后缀。

根据文档,我得到的印象是 Keccak 最初没有域后缀概念,并且 Keccak 团队提供的已知答案测试要求不使用域后缀。

所以,对于你的问题。如果我们将字符串“测试”并使用 ASCII 或 UTF-8 编码将其转换为字节数组(因为 Keccak 处理二进制,因此必须首先将文本转换为字节或位,因此决定使用哪种字符编码很重要使用)然后将其提供给真正的 SHA3-224 散列函数,我们将得到以下结果(以十六进制表示,一行 16 个字节以便于阅读):

37 97 BF 0A FB BF CA 4A 7B BB A7 60 2A 2B 55 27
46 87 65 17 A7 F9 B7 CE 2D B0 AE 7B

SHA3​​-224 可以概括为“在输入消息之后和多速率填充之前附加 01”Keccak[1152, 448](M || "01", 224)的意思。M || "01"

但是,如果没有域后缀,我们会得到Keccak[1152, 448](M, 224)lonesomeM意味着没有附加后缀位,并且多速率填充将在输入消息之后立即开始。如果我们将您的相同输入“测试”消息提供给这个不使用域后缀的 Keccak 函数,那么我们会得到以下结果(再次以十六进制表示):

3B E3 0A 9F F6 4F 34 A5 86 11 16 C5 19 89 87 AD
78 01 65 F8 36 6E 67 AF F4 76 0B 5E

所以这个结果表明该函数不是 SHA3-224

这一切都意味着您看到的输出差异完全由是否存在“01”域后缀来解释(这是我在阅读您的问题时立即怀疑的)。任何声称是 SHA3 的东西都必须使用“01”域后缀,因此要非常警惕行为不同的工具。仔细检查文档以确保它们不要求您在创建/使用对象或函数时指定所需的域后缀,但任何声称是 SHA3 的东西确实不应该使忘记后缀位成为可能。

于 2017-05-22T21:01:06.430 回答
1

这是 Qt 中的一个错误,并在此处报告并在 Qt5.9 中修复

于 2017-08-22T02:58:37.213 回答