On Sat, Jun 09, 2012 at 09:52:07AM -0400, Anantha Kasetty wrote: > Had to dust up my long forgotten Perl skills, here is a sample program > > use URI::Escape; > use Digest::SHA qw(hmac_sha1_base64); > > sub hmac_digest { > my $uri = shift @_; > my $key = shift @_; > > $digest = hmac_sha1_base64($uri, $key); > > #@#$%! perl does not pad the output of base64 > > while (length($digest) % 4) { > $digest .= '='; > } > return $digest; > } > > sub escape_hash { > my %hash = @_; > my @pairs; > > for my $key (sort keys %hash) { > push @pairs, join "=", map { uri_escape($_) } lc($key), > lc($hash{$key}); > } > return join "&", @pairs; > } > > my $secret_key = > 'kNd2VxlXxCXwyJGlidr0ZcmcqXSH2refwxZTStD6If4vJu4QmJPOIui0rgr88mDI6DuGQTzP9e > QNOjlZBTReKg' ; > > > my $uri = escape_hash( > 'apikey'=>'8v_gevjjgdjbbhibmlle4yyhkseqhrefztnv4up2fu3k9y12th7lscsn6-7seago > 1ycctnute1ot0v7npcus8q', > 'command'=>'listZones', > 'response'=>'json'); > > $signature = uri_escape(hmac_digest($uri, $secret_key)); > > $uri .= "&signature=$signature"; > print "$uri\n"; >
This didn't quite work when run but does give out the same signature as my python script below that works. The only difference I see is that the arguments in the final request in your script is lower cased but in my script I retain the case. root@cloud:~# perl api_sign.pl BdHeONSolrYr92FE04%2FLkuAVCjA%3D apikey=ssszixygqdb4v4lvdtezasmrtjqi-wwnphd-3_fra5esibrikgclxwobhryhldsl3ayi7heedww0rtwhk9thew&command=listzones&response=json&signature=BdHeONSolrYr92FE04%2FLkuAVCjA%3D root@cloud:~# python api_sign.py BdHeONSolrYr92FE04%2FLkuAVCjA%3D apiKey=SssziXYGqdB4V4lvdTeZasmrTJQi-WWNphD-3_FRa5EsibrIkgcLXwoBHRyhlDsl3aYI7heEdWW0RtwhK9thew&command=listZones&response=json&signature=BdHeONSolrYr92FE04%2FLkuAVCjA%3D #!/usr/bin/env python import urllib2 import urllib import hmac import hashlib import base64 def make_request(requests, secretKey): request = zip(requests.keys(), requests.values()) request.sort(key=lambda x: str.lower(x[0])) requestUrl = "&".join(["=".join([r[0], urllib.quote_plus(str(r[1]))]) for r in request]) hashStr = "&".join(["=".join([str.lower(r[0]), str.lower(urllib.quote_plus(str(r[1]))).replace("+", "%20")]) for r in request]) sig = urllib.quote_plus(base64.encodestring(hmac.new(secretKey, hashStr, hashlib.sha1).digest()).strip()) print "Signature: %s"%sig requestUrl += "&signature=%s"%sig print requestUrl if __name__ == '__main__': requests = { "apiKey": "SssziXYGqdB4V4lvdTeZasmrTJQi-WWNphD-3_FRa5EsibrIkgcLXwoBHRyhlDsl3aYI7heEdWW0RtwhK9thew", "response" : "json", "command" : "listZones" } secretKey = "dKGxVNF_mcBq_ZhvO9YY7lzQzkckdRQ-CQ5MIAymQYhvt141_6j-AVwGbtmjoswh84uvv_r_GFOIF9hWHoZaXw" make_request(requests, secretKey) I'll put all the examples in different languages on the wiki because this will come up in the future on the lists. Any takers for a Ruby/.NET implementation? -- Prasanna.,