tags:

views:

516

answers:

2

I have a small code snippet that I'm trying to get to work in Ruby.

digest = HMAC.digest(Digest.new(SHA1), Base64.decode64(key), HashString) return Base64.encode64(digest.to_s()).chomp()

I tried it as follows:

hashstring = "POST application/octet-stream
Thu, 05 Jun 2008 16:38:19 GMT /rest/objects date:Thu, 05 Jun 2008 16:38:19 GMT groupacl:other=NONE listable-meta:part4/part7/part8=quick meta:part1=buy
id: 6039ac182f194e15b9261d73ce044939/user1 useracl:jane=FULL_CONTROL,juan=WRITE"

key = "AKLuryj6zs8ste4Y3jTGQp71xq0="


def hash(hs, keyh)
  digest = HMAC.digest(Digest.new(SHA1), Base64.decode64(keyh), hs)
  return Base64.encode64(digest.to_s()).chomp()
end

puts hash hashstring,key

this gives me the error file.rb:1:in `require': no such file to load -- hmac-md5 (LoadError) from file.rb:1

I'm unfamiliar with ruby or how include/require modules work. (or if they are bundled with the language or require seperate downloading. What file/code am I missing to make this function?

+4  A: 

You need to install the ruby-hmac module. See this blog post for a gentle introduction.

Jonathan Feinberg
OpenSSL has been part of the Ruby standard library for *ages*. There is no need to install anything.
Jörg W Mittag
Following that blog post fixed the problem
stormist
A: 

There seems to be something seriously wrong. Ruby tells you that are trying to call require in the first line of your script, and that it can't find the file that your are telling it to load. But! You don't call require in the first line of your script! In fact, you don't call require anywhere in your script.

Something must be severely broken.

One potential problem I see in your code, is that hash is a standard method in Ruby, that is already defined for a totally different purpose. Overriding it is probably going to lead to problems sooner or later. However, the error you are seeing happens way before we even get to that, so it's not relevant for the immediate problem at hand.

As far as I can make out, this seems to be what you are trying to do:

require 'openssl'
require 'base64'

DIGEST = OpenSSL::Digest::Digest.new('sha1')

def hmac(hs, keyh)
  digest = OpenSSL::HMAC.digest(DIGEST, Base64.decode64(keyh), hs)
  return Base64.encode64(digest).chomp
end

require 'test/unit'
class TestHmac < Test::Unit::TestCase
  def test_that_the_hmac_gets_computed_correctly
    hashstring = 'POST application/octet-stream
Thu, 05 Jun 2008 16:38:19 GMT /rest/objects date:Thu, 05 Jun 2008 16:38:19 GMT groupacl:other=NONE listable-meta:part4/part7/part8=quick meta:part1=buy
id: 6039ac182f194e15b9261d73ce044939/user1 useracl:jane=FULL_CONTROL,juan=WRITE'
    key        = 'AKLuryj6zs8ste4Y3jTGQp71xq0='
    assert_equal 'KxQMJeaVqxFdujha89UuksEUiAg=', hmac(hashstring, key)
  end
end

But I am still puzzled how you can get an error message from require when you are never calling it in the first place.

Jörg W Mittag
Is he showing us the entirety of his code? Maybe he does call `require` somewhere.
Sarah Vessels