Sat, 31 Jan 09

Implementing Version 2 of the Amazon AWS HTTP Request Signature in Ruby

This took me a long time to work out this afternoon so I guess it might be useful to others. I couldn’t find an implementation (of version 2 of the request signing) in any of the existing Amazon AWS libraries and although I did find a promising looking post here it just didn’t work for me. I ended up using the Simple DB PHP sample code to obtain some test data1 that I could use to debug my own code2 and eventually got it working.

1 I plan to post some test data (to help others attempting to write a client) in a follow up post.

2 I printed the parameters and signature at various stages of the request so that I could compare it to the output from my client.

require 'rubygems'
require 'cgi'
require 'time'
require 'hmac'
require 'hmac-sha2'
require 'base64'

ACCESS_IDENTIFIER = 'your-access-identifier'
SECRET_IDENTIFIER = 'your-secret-identifier'


params = {
  'Action' => 'ListDomains',
  'SignatureMethod' => 'HmacSHA256',
  'SignatureVersion' => 2,
  'Timestamp' =>,
  'Version' => '2007-11-07'

canonical_querystring = params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
string_to_sign = "GET

hmac =
signature = Base64.encode64(hmac.digest).chomp # chomp is important!  the base64 encoded version will have a newline at the end

params['Signature'] = signature
querystring = params.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&') # order doesn't matter for the actual request

puts `curl -X"GET" "\#{AMAZON_ENDPOINT}?\#{querystring}" -A"simple ruby aws sdb wrapper"`