Почему Crypto ++ и Ruby генерируют несколько разные хэши SHA-1?

Я использую две разные библиотеки для генерации хеша SHA-1 для использования при проверке файлов - более старая версия Библиотека Crypto ++ и класс Digest :: SHA1, реализованные в Ruby. Хотя я видел другие случаи несовпадающих хэшей, вызванных различиями в кодировке, две библиотеки выводят хэши, которые почти идентичны.

Например, передача файла через каждый процесс приводит к следующим результатам:

Crypto ++ 01c15e4f46d8181b984fa2a2c740f8f67130acac

Ruby: eac15e4f46d8181b984fa2a2c740f8f67130acac

Как видите, только первые два символа строки хеша различны, и это поведение повторяется во многих файлах. Я взглянул на исходный код для каждой реализации, и единственное отличие, которое я обнаружил на первый взгляд, было в шестнадцатеричном формате данных, который используется для 160-битного хэширования. Я понятия не имею, как этот гекс используется в алгоритме, и я подумал, что, скорее всего, мне будет проще задать вопрос, если кто-то сталкивался с этой проблемой раньше.

Я включил данные из соответствующих библиотек ниже. Я также включил значения из OpenSSL, поскольку каждая из трех библиотек имела немного разные значения.

Crypto ++:

digest[0] = 0x67452301L;
digest[1] = 0xEFCDAB89L;
digest[2] = 0x98BADCFEL;
digest[3] = 0x10325476L;
digest[4] = 0xC3D2E1F0L;

Ruby:

context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;

OpenSSL:

#define INIT_DATA_h0 0x67452301UL
#define INIT_DATA_h1 0xefcdab89UL
#define INIT_DATA_h2 0x98badcfeUL
#define INIT_DATA_h3 0x10325476UL
#define INIT_DATA_h4 0xc3d2e1f0UL

Кстати, вот код, который используется для генерации хэша в Ruby. У меня нет доступа к исходному коду для реализации Crypto ++.

File.class_eval do
    def self.hash_digest filename, options = {}
        opts = {:buffer_length => 1024, :method => :sha1}.update(options)
        hash_func = (opts[:method].to_s == 'sha1') ? Digest::SHA1.new : Digest::MD5.new
        open(filename, "r") do |f|
            while !f.eof
                b = f.read
                hash_func.update(b)
            end
        end
        hash_func.hexdigest
    end
end
4 голоса | спросил Ryan Bright 18 PM000000110000002731 2010, 23:02:27

1 ответ


0

Я полагаю, что вы печатаете хэши SHA-1 на один байт. Можем ли мы увидеть код, который их печатает? Если нет, вот несколько потенциально полезных методов диагностики:

  1. Создайте очень короткий файл (скажем, одно слово) и поместите его содержимое в виде шестнадцатеричной строки в http://www.fileformat.info/tool/hash.htm . Однако вам нужно точно знать шестнадцатеричное содержимое файла. Вы можете использовать xxd для этого в Unix, но вам придется остерегаться проблем с порядком байтов. Я не уверен, как это сделать на других ОС.

  2. Всегда ли при запуске одного и того же файла в одной и той же реализации SHA-1 всегда выводится одно и то же значение в этом первом байте? Если да, меняется ли это значение при изменении файлов?

ответил DAMF 19 AM00000050000005731 2010, 05:11:57

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132