2012-07-22 65 views
3

我正在將一些現有的代碼從Python重寫到Ruby,而且我遇到了一個奇怪的錯誤,我似乎無法弄清楚。在這裏,我們有Python代碼(工作):紅寶石HMAC-SHA與Python的區別

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

輸出:0x64F461D377D9930C

而紅寶石(我是新來的)代碼:

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

輸出:0x563FDAF11E63277C

什麼可能導致這種差異?

回答

5

你犯了兩個錯誤:

  1. Python的hmac.new需要關鍵,手段,消化 - 所以你應該寫

    hmac.new( 「絕密」,數據+ 「\ 0」, sha)

  2. Ruby中OpenSSL :: Digest的默認摘要方法不是SHA1(我不確定它是什麼)。你應該只使用:

    的OpenSSL :: HMAC.hexdigest( 'SHA1', 「絕密」,數據+ 「\ 0」)[0,16]

兩種方法(先在Python中,第二在Ruby中)返回相同的輸出。

4

除了蓋伊阿迪尼的答案 - 在Ruby中SHA是蟒蛇sha不同的是sha1(在sha.pyfrom 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 
+0

酷 - 那麼哪個版本的SHA是ruby的默認SHA算法?哪一個是python的? Python中的默認版本沒有返回與sha1算法相同的值。 – 2012-07-22 09:43:34

+0

Python中的缺省摘要是md5(如果'new()'函數中沒有指定摘要)。 – Tisho 2012-07-22 09:53:00

+0

謝謝 - 但我的意思是,當Lander寫出des_key = hmac.new(data +「\ 0」,「SUPERSECRET」,sha).digest()[0:8]時,他得到的結果與任何al algo ...那他得到了哪個沙(我猜不是md5)。 – 2012-07-22 10:01:09