Неправильное поведение при генерации хэша SHA3 с помощью cryptopp

Я вижу очень странную разницу в поведении при создании хэшей SHA3 с помощью cryptopp на RHEL7 и Debian9. Если вместо этого я использую хэш SHA1 или MD5, результат будет идентичен на обеих платформах. Я сократил его до следующей минимальной программы:

#include <iostream>
#include <cryptopp/sha3.h>
#include <cryptopp/filters.h>
#include <cryptopp/hex.h>

using namespace CryptoPP;

int main(int argc, const char* argv[])
{
   {
      CryptoPP::SHA3_256 sha256;
      std::string hash = "";
      StringSource("", true, new HashFilter(sha256, new HexEncoder(new StringSink(hash))));
      std::cout << "hash='" << hash << "'\n";
   }
   {
      CryptoPP::SHA3_256 sha256;
      std::string hash = "";
      StringSource("{}", true, new HashFilter(sha256, new HexEncoder(new StringSink(hash))));
      std::cout << "hash='" << hash << "'\n";
   }
}

В Debian вывод:

hash='A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A'
hash='840EB7AA2A9935DE63366BACBE9D97E978A859E93DC792A0334DE60ED52F8E99'

что правильно в соответствии с онлайн-конвертером на https://emn178.github.io/online-tools/sha3_256.html

Но на RHEL7 вывод странный:

hash='C5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470'
hash='B48D38F93EAA084033FC5970BF96E559C33C4CDC07D889AB00B4D63F9590739D'

Так что либо я что-то не так делаю, либо ошибка в библиотеке, либо неправильная установка.

Я неправильно использую libcryptopp? Что-то вроде отсутствующего MessageEnd()?

На RHEL7:

>ldd ./hashtest 
    linux-vdso.so.1 =>  (0x00007ffecd1b1000)
    libcryptopp.so.6 => /lib64/libcryptopp.so.6 (0x00007f71c3707000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f71c3400000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f71c31ea000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f71c2e1d000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f71c2c01000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f71c28ff000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f71c3e2e000)
>file /lib64/libcryptopp.so.6.0.0 
/lib64/libcryptopp.so.6.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=4a0941023c6e957077cb555536a509a0ef93bf04, stripped

В Дебиане:

>ldd ./hashtest 
    linux-vdso.so.1 (0x00007ffedc5e6000)
    libcrypto++.so.6 => /usr/lib/x86_64-linux-gnu/libcrypto++.so.6 (0x00007f1d3b79a000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1d3b418000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1d3b201000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1d3ae62000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1d3ac45000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1d3a941000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f1d3bf35000)
>file /usr/lib/x86_64-linux-gnu/libcrypto++.so.6.0.0 
/usr/lib/x86_64-linux-gnu/libcrypto++.so.6.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=5c6cb06479005d2ebfa40c75e5489c915d314b70, stripped

Кажется, это v6.0.0 на обеих платформах, но:

>apt-cache show crypto++
[snip]
Package: libcrypto++-dev
Source: libcrypto++
Version: 5.6.4-7

>yum info --enablerepo=epel cryptopp
Installed Packages
Name        : cryptopp
Arch        : x86_64
Version     : 5.6.2
Release     : 10.el7
Size        : 5.2 M
Repo        : installed
From repo   : epel
Summary     : C++ class library of cryptographic schemes
URL         : http://www.cryptopp.com/
Licence     : Boost
Description : Crypto++ Library is a free C++ class library of cryptographic schemes.
            : See http://www.cryptopp.com/ for a list of supported algorithms.
            : 
            : One purpose of Crypto++ is to act as a repository of public domain
            : (not copyrighted) source code. Although the library is copyrighted as a
            : compilation, the individual files in it are in the public domain.

person Bruce Adams    schedule 06.07.2018    source источник


Ответы (1)


Вам нужно, чтобы ваш блок RHEL был по крайней мере до версии cryptopp 5.6.4, потому что именно здесь появилась «настоящая» реализация SHA3. До 5.6.4 реализация использовала исходную схему заполнения, указанную в предложении «Keccak», которое было выбранной в качестве основы SHA3, а не модифицированной схемы заполнения, которая была определена в ратифицированном стандарте SHA3.

Подробнее см. https://github.com/weidai11/cryptopp/issues/158. и комментарии к выпуску в нижней части https://github.com/weidai11/cryptopp для уведомления. изменения в 5.6.4.

person ottomeister    schedule 07.07.2018
comment
Тонкий. Без поиска в Google я бы не знал, что переход на FIPS 202 означает изменение экспериментальной реализации в соответствии с опубликованным стандартом! Примечание для авторов документации. И удивительно, что EPEL также содержит устаревшую версию. - person Bruce Adams; 09.07.2018
comment
Предполагая, что ваш ответ правильный, я отправил это как ошибку в EPEL здесь: bugzilla. redhat.com/show_bug.cgi?id=1599242 - person Bruce Adams; 09.07.2018