3

我正在将一些现有代码从 Python 重写为 Ruby,并且遇到了一个我似乎无法弄清楚的奇怪错误。这里我们有 Python 代码(有效):

import sha, hmac
data = 'sampledata'
data = data.encode('ascii')
des_key = hmac.new(data + "\0", "SUPERSECRET", sha).digest()[0:8]

输出:0x64F461D377D9930C

Ruby(我是新手)代码:

require 'openssl'
digest  = OpenSSL::Digest::SHA.new
data = 'sampledata'
data.encode!('ascii')
puts OpenSSL::HMAC.hexdigest(digest, "SUPERSECRET", data + "\0")[0, 16]

输出:0x563FDAF11E63277C

什么可能导致这种差异?

4

2 回答 2

5

你犯了两个错误:

  1. Python 的 hmac.new 需要键、方法和摘要——所以你应该写

    hmac.new("SUPERSECRET",data + "\0", sha)

  2. Ruby 中 OpenSSL::Digest 的默认摘要方法不是 SHA1(我不确定它是什么)。你应该只使用:

    OpenSSL::HMAC.hexdigest('sha1',"SUPERSECRET",data+"\0")[0,16]

两种方法(第一个在 Python 中,第二个在 Ruby 中)返回相同的输出。

于 2012-07-22T09:23:58.870 回答
4

除了 Guy Adini 的回答 - 在 Ruby 中,SHA 与 python 不同,sha它是sha1(in sha.py: from hashlib import sha1 as sha):

from hashlib import *
import hmac
data = 'sampledata'
data = data.encode('ascii')

algo = [sha1, sha224, sha256, sha512]
for al in algo:
    print al().name, hmac.new("SUPERSECRET", data + "\0", al).hexdigest()[0:16]

产生:

sha1 50c61ea49195f03c
sha224 fd6a418ee0ae21c8
sha256 79deab13bd7b041a
sha512 31561f9c9df69ab2

在红宝石中:

require 'openssl'
data = 'sampledata'
data.encode!('ascii')
%w(sha sha1 sha224 sha256 sha512).each do |al|
  puts "#{al}: #{OpenSSL::HMAC::hexdigest(al, "SUPERSECRET", "#{data}\0")[0,16]}"
end

产生:

sha: 563fdaf11e63277c
sha1: 50c61ea49195f03c
sha224: fd6a418ee0ae21c8
sha256: 79deab13bd7b041a
sha512: 31561f9c9df69ab2
于 2012-07-22T09:38:04.250 回答