我正在使用两个不同的库来生成用于文件验证的 SHA-1 哈希 - Crypto++库的旧版本和由 Ruby 实现的 Digest::SHA1 类。虽然我见过其他由编码差异导致的哈希不匹配的实例,但这两个库输出的哈希几乎相同。
例如,通过每个进程传递一个文件会产生以下结果:
加密++ 01c15e4f46d8181b984fa2a2c740f8f67130acac
红宝石:eac15e4f46d8181b984fa2a2c740f8f67130acac
如您所见,只有哈希字符串的前两个字符不同,并且这种行为在许多文件中重复出现。我查看了每个实现的源代码,乍一看,我发现的唯一区别在于用于 160 位散列的数据十六进制。我不知道该十六进制是如何在算法中使用的,而且我认为如果有人以前遇到过这个问题,我可能会更快地提出这个问题。
我已经包含了来自下面各个库的数据。我还包括了来自 OpenSSL 的值,因为这三个库中的每一个都有略微不同的值。
加密++:
digest[0] = 0x67452301L;
digest[1] = 0xEFCDAB89L;
digest[2] = 0x98BADCFEL;
digest[3] = 0x10325476L;
digest[4] = 0xC3D2E1F0L;
红宝石:
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