c++ - 为什么 Crypto++ 和 Ruby 生成的 SHA-1 哈希略有不同?

标签 c++ ruby hash sha1 crypto++

我正在使用两个不同的库来生成 SHA-1 哈希以用于文件验证 - Crypto++ 的旧版本库和由 Ruby 实现的 Digest::SHA1 类。虽然我见过其他由编码差异导致的不匹配哈希值的实例,但这两个库输出的哈希值几乎相同。

例如,通过每个进程传递一个文件会产生以下结果:

加密++ 01c15e4f46d8181b984fa2a2c740f8f67130acac

ruby : eac15e4f46d8181b984fa2a2c740f8f67130acac

如您所见,只有哈希字符串的前两个字符不同,并且这种行为在许多文件中重复出现。我查看了每个实现的源代码,乍一看,我发现的唯一区别在于用于 160 位散列的数据十六进制。我不知道这个十六进制在算法中是如何使用的,我想如果有人以前遇到过这个问题,我问这个问题可能会更快。

我在下面包含了来自各个库的数据。我还包含了来自 OpenSSL 的值,因为这三个库中的每一个都具有略微不同的值。

加密++:

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

最佳答案

我猜你在打印出 SHA-1 散列时差了一个字节。我们能看到打印它们的代码吗?如果没有,这里有一些可能有用的诊断:

  1. 创建一个非常短的文件(比如,一个单词),并将其内容作为十六进制字符串放在 http://www.fileformat.info/tool/hash.htm 中。 .不过,您需要确切地知道文件的十六进制内容。您可以在 Unix 上使用 xxd,但您必须注意字节顺序问题。我不确定如何在其他操作系统上执行此操作。

  2. 通过相同的 SHA-1 实现多次运行相同的文件是否总是在第一个字节中打印出相同的值?如果是这样,当您更改文件时该值是否会发生变化?

关于c++ - 为什么 Crypto++ 和 Ruby 生成的 SHA-1 哈希略有不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3515694/

相关文章:

ruby - Mechanize 和 NTLM 身份验证

c# - c#如何计算出对象的哈希码?

algorithm - 游戏研究/理解玩家 ID 的生成

c++ - 要求通过 static_cast<double>(x) 显式调用运算符 double()

c++ - 为什么这个 OpenCV 代码什么都不做?

c++ - 在 C++ 中创建头文件时出错

php - 什么是 Ruby 等同于 PHP 的紧凑型?

c++ - boost::序列化和工厂模式设计

ruby - 验证带有扩展名的电话号码格式

algorithm - 使用开放链和单独寻址检查成员资格