NiroshaDogra
NiroshaDogra

Reputation: 21

Matching Signed Headers Encrypted in Ruby on Rails and JavaScript

I am using ApiAuth gem (as found here) to sign my request. I am also writing my own JavaScript code using CryptoJS (as found here) to provide authentication by checking the encrypted header generated by ApiAuth against the one generated by my code.

Given below is a code snippet from ApiAuth Gem:

def hmac_signature(headers, secret_key, options)
  if options[:with_http_method]
    canonical_string = headers.canonical_string_with_http_method(options[:override_http_method])
  else
    canonical_string = headers.canonical_string
  end
  digest = OpenSSL::Digest.new('sha1')
  b64_encode(OpenSSL::HMAC.digest(digest, secret_key, canonical_string))
end

Here is the code I have written as an equivalent in JavaScript:

function hmacSignature(request, appSecret) {
 return CryptoJS.HmacSHA1(canonicalString(request), appSecret).toString(CryptoJS.enc.Base64);}

These two don't generate the same encrypted header. I tried using jsSHA to do the same thing and while the encrypted header generated by jsSHA and CryptoJS is the same, they don't match the one generated by ApiAuth.

Kindly help me figure out how to make this work.

EDIT:

Taking Canonical String as "message" and appSecret as "secret" I get the same values from ApiAuth and CryptoJS which is:

DK9kn+7klT2Hv5A6wRdsReAo3xY=

I've figured out that the problem in my original code is coming because the timestamp set in my JS code and the one set in the ApiAuth don't match.

Upvotes: 1

Views: 334

Answers (1)

NiroshaDogra
NiroshaDogra

Reputation: 21

I fixed my problem and am writing this answer in hopes that it helps someone else looking for a solution to this problem.

  1. Let me start off by saying that the two encryptions should be the same whether they are encrypted in Ruby or JS or any other language.
  2. It is important to check that every portion of the input sent to both places is exactly the same and completely identical.

When I checked my inputs to the JS file and the gem, I realised that for some reason the time-stamp (which I was setting in the JS file) wasn't getting sent correctly to the gem.

I debugged my code step by step and figured out where the mistake was. I am outlining some of the possible issues below:

  1. I was setting the timestamp in my JS as follow

    request.headers["DATE"]

I realised that this wasn't getting set correctly so I had to change "DATE" to "DATE1" and accordingly change the rest of my code. This worked.

  1. Second, the timestamp I was sending wasn't compatible with the HTTP GST type timestamp that was expected by the gem. This is another thing that you must keep in mind when sending the timestamp.

Upvotes: 0

Related Questions