0

I'm trying to follow the steps Mandrill has outlined here http://help.mandrill.com/entries/23704122-Authenticating-webhook-requests in order to validate incoming requests. I've setup a test requestb.in with the url seen in the code. I want this method to return the mandrill signature, which in this case is H7Zky1B/GShKH4kuQcfUhNrQq+k= but instead it returns a different value each time. Where am I going wrong?

php code sample as provided by mandrill

function generateSignature($webhook_key, $url, $params) {
    $signed_data = $url;
    ksort($params);
    foreach ($params as $key => $value) {
        $signed_data .= $key;
        $signed_data .= $value;
    }

    return base64_encode(hash_hmac('sha1', $signed_data, $webhook_key, true));
}

my ruby code

 def valid?(params)
    wh_key = "Ny_lzk4zxENbNVezqECBxw"
    url = "http://requestb.in/15wvu0y1"
    signed_data = url
    params.sort.each do |key, value|
      signed_data += (key.to_s + value.to_s)
    end
    digest = OpenSSL::Digest.new('sha1')
    Base64.encode64("#{OpenSSL::HMAC.digest(digest,signed_data,wh_key)}") 
  end
agarrow
  • 457
  • 2
  • 7
  • 17

2 Answers2

1

You'll definitely need the full URL, including the http:// at the beginning. It looks like the parameters you're passing in the second to last line may not be in the correct order. This should work, though, assuming the parameters have already been form-decoded:

def valid?(webhook_key, url, params, signature)
  data = url
  params.sort.each {|k,v| data = url + k + v}
  digest = OpenSSL::Digest::Digest.new('sha1')
  expected = Base64.encode64(OpenSSL::HMAC.digest(digest, webhook_key, data)).strip
  expected == signature
end 
Kaitlin
  • 6,167
  • 32
  • 30
  • Also important to note that the params noted above are the POST params (including the mandrill_events param from Mandrill) and NOT the params attached to the Webhook Route – Will Nathan Jul 05 '13 at 00:40
  • @JeremyHaile - I'd recommend starting a new topic with information about what specifically isn't working, or getting in touch with the Mandrill support team via the Support button in your account. If it's not working, more details would be needed about the specific issue you're seeing. – Kaitlin Oct 21 '13 at 01:25
1

This worked for me:

data = "http://my_awesome.com/api/webhook_action"

request.POST.sort_by { |key, value| key.to_i }.each do |key,value|

    data += key.to_s.strip
    data += value.to_s.strip

end

digest = OpenSSL::Digest::Digest.new('sha1')
expected = Base64.encode64("#{OpenSSL::HMAC.digest(digest,test_key, data)}").strip

The strip methods might be overkill though.

Alex C
  • 1,334
  • 2
  • 18
  • 41