3

I'm rewriting some existing code from Python to Ruby, and I've across a strange error that I can't seem to figure out. Here we have the Python code (which works):

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

Output: 0x64F461D377D9930C

And the Ruby (which I'm new to) code:

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

Output: 0x563FDAF11E63277C

What could be causing this difference?

2 Answers 2

5

You made two mistakes:

  1. Python's hmac.new takes key, method, digest - so you should write

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

  2. The default digest method for OpenSSL::Digest in Ruby isn't SHA1 (I'm not sure what it is). You should just use:

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

Both methods (first in Python, second in Ruby) return the same output.

Sign up to request clarification or add additional context in comments.

Comments

4

In addition to Guy Adini's answer - in Ruby SHA is different from python sha which is 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]

produces:

sha1 50c61ea49195f03c
sha224 fd6a418ee0ae21c8
sha256 79deab13bd7b041a
sha512 31561f9c9df69ab2

and in 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

produces:

sha: 563fdaf11e63277c
sha1: 50c61ea49195f03c
sha224: fd6a418ee0ae21c8
sha256: 79deab13bd7b041a
sha512: 31561f9c9df69ab2

5 Comments

Cool - so which version of SHA is ruby's default SHA algorithm? And which one is python's? The default version in Python didn't return the same value as the sha1 algorithm.
The default digest in Python is md5(if no digest is specified in new() function).
Thanks - but I mean, when Lander wrote des_key = hmac.new(data + "\0", "SUPERSECRET", sha).digest()[0:8], he got a result which didn't match any of al in algo... So which sha did he get (not md5, I guess).
Not quite sure, but the 'SHA' in Ruby seems to be 'SHA0', which is deprecated in Python from a long time, as it is easy to crack...
Thank you for the info! That's a very nice representation, and since I'm new to Ruby I learned an easy way to write word arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.