Search code examples
ruby-on-railshmacsha1

HMACSHA1 in Rails - strange result


I am trying to implement Single Sign On feature for Disquss. Disquss has a test console, which enables us to quickly test the values. First, we made sure that we got the hard coded values to work with the console, so we are certain we understand Disquss requirements. Next, we wanted to implement the same thing in rails, but we got issue here.

Problem is in the fact that ruby is not generating expected values, in fact it generates junk, which is totally different form the expected values:

THis is from Disquss manual:

The message body (Base64-encoded)

The message body must include the following case sensitive properties unless noted otherwise:

id - any unique user ID associated with that account within your user database. This will be used to generate a unique username to reference in the Disqus system. IDs must be completely unique; if you're using multiple datastores locally, for example, make sure not to re-use IDs when passing them to Disqus as that will result in account conflicts.
username - The displayed name for that account
email - The registered email address for that account
avatar (optional) - A link to that user's avatar
url (optional) - A link to the user's website

HMAC-SHA1 signature

Generated using HMAC->SHA1(secret_key, message + ' ' + timestamp)

Following that example we devised thew following rails code (it is still in testing phase, hence the puts):

secret_key = "12312312312312312312312312312312312312312312312312"
  digest  = OpenSSL::Digest::Digest.new('sha1')
  puts  @disqus_timestamp = Date.today.to_time.to_i
  puts  @disqus_serializer_message = {"id"=> session[:frontend_user].to_s,"username"=>@fuser.username,"email"=>@fuser.email }.to_json
  puts  @disqus_message = Base64.encode64(@disqus_serializer_message)      
  puts  @disqus_signature  = OpenSSL::HMAC.digest(digest,secret_key,@disqus_message + ' '+ @disqus_timestamp.to_s )
  puts  @sso_payload = ""
  puts "END"

We should get three values: 1. JSON serialized in format such as:

eyJ1c2VybmFtZSI6InZlZHJhbiBtYXJpY2V2aWMiLCJpZCI6IjgiLCJlbWFp bCI6IndleC5hbHBoYUBnbWFpbC5jb20ifQ==

Json Works

  1. Computed HMAC: We are getting this type of format:

5œ[ƒmò Ø™`Õ„Öù©≠∆8

but we should be getting something in this format:

4683eff451100191c60d2a0f0e72f3a6d15db950

I tried different things, but to no avail. What might be the problem?


Solution

  • OpenSSL::HMAC.digest outputs the raw bytes, whereas you appear to want the hexadecimal representation

    OpenSSL::HMAC.hexdigest will output in hex format. You can of course convert it yourself too:

    arbitary_data.unpack('H*').first

    will hex-encode all the bytes.