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.,