QCryptographicHash - что такое SHA3 в реальности?

Я получил такой кусок кода:

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 надлежащим образом и откуда мы это знаем?

2 ответа

Сейчас я пишу библиотеку Keccak для Java, поэтому у меня были игрушки, чтобы проверить первоначальные подозрения.

Сначала краткое резюме. 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, требуют, чтобы суффикс домена не использовался.

Итак, к вашей проблеме. Если мы возьмем String "test" и преобразуем его в байтовый массив, используя кодировку 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 можно обобщить как Keccak[1152, 448](M || "01", 224) где M || "01" означает "добавить 01 после входного сообщения и перед многоскоростным заполнением".

Однако без доменного суффикса мы получаем Keccak[1152, 448](M, 224) где одинокий M означает, что никакие суффиксные биты не добавляются, и многоскоростное заполнение начнется сразу после входного сообщения. Если мы передадим ваше же входное "тестовое" сообщение этой функции 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, на самом деле не должно позволить забыть биты суффикса.

Это ошибка в Qt, о которой сообщалось здесь и исправленная в Qt5.9

Другие вопросы по тегам