【问题标题】:Ruby HMAC-SHA Differs from PythonRuby HMAC-SHA 与 Python 不同
【发布时间】:2012-07-20 21:06:35
【问题描述】:

我正在将一些现有代码从 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

造成这种差异的原因是什么?

【问题讨论】:

    标签: python ruby sha hmac


    【解决方案1】:

    你犯了两个错误:

    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 中)返回相同的输出。

    【讨论】:

      【解决方案2】:

      除了 Guy Adini 的回答 - 在 Ruby 中,SHA 不同于 python sha,即 sha1(在 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
      

      在 Ruby 中:

      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
      

      【讨论】:

      • 酷 - 那么哪个版本的 SHA 是 ruby​​ 的默认 SHA 算法?哪一个是蟒蛇的? Python 中的默认版本没有返回与 sha1 算法相同的值。
      • Python中默认的摘要是md5(如果new()函数中没有指定摘要)。
      • 谢谢 - 但我的意思是,当 Lander 写 des_key = hmac.new(data + "\0", "SUPERSECRET", sha).digest()[0:8] 时,他得到了一个结果这与算法中的任何一个都不匹配......所以他得到了哪个 sha(我猜不是 md5)。
      • 不太确定,但 Ruby 中的 'SHA' 似乎是 'SHA0',在 Python 中已被弃用很长时间了,因为它很容易破解...
      • 感谢您提供的信息!这是一个非常好的表示,因为我是 Ruby 新手,所以我学会了一种编写单词数组的简单方法。
      猜你喜欢
      • 2015-09-07
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-10
      • 2016-04-29
      相关资源
      最近更新 更多