<div dir="ltr">On 8 April 2015 at 21:47,  <span dir="ltr"><<a href="mailto:lloyd@writersglen.com" target="_blank">lloyd@writersglen.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
I'm striving to look up books in Amazon's db by ISBN. At first blush it looks easy enough:<br>
<br>
<a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/EX_LookupbyISBN.html" target="_blank">http://docs.aws.amazon.com/AWSECommerceService/latest/DG/EX_LookupbyISBN.html</a><br>
<br>
But the last item, Signature, baffles me. Procedure here:<br>
<br>
<a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html" target="_blank">http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html</a><br>
<br>
I'm fine with this until I hit step 4:<br>
<br>
-- Sort parameter/value pairs by byte value --- I can see how to do this manually, but don't know how put Erlang to the task<br>
<br>
And I'm really stumped when I hit step 8:<br>
<br>
-- Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm<br>
<br>
Any help? Better yet, does anyone have actual code to make such requests they're willing to share?<br>
<br></blockquote><div><br></div><div>Sorry, quite a late reply here, but better late than never I guess. Here is some sample code I dug out of one of my pet projects.<br><font size="2"><span style="font-family:monospace,monospace"><br>sign_amazon_aws_req(Method, Params) -><br>    {ok, {AWS_Access_id, Secret_key}} = application:get_env(my_app, aws_access_credentials),<br><br>    Boiler_plate_params = <br>        ["Service=AWSECommerceService",<br>         "AWSAccessKeyId=" ++ AWS_Access_id,<br>         "AssociateTag=my_associate_tag",<br>         "Timestamp=" ++ http_uri:encode(aws_timestamp())<br>        ],<br>    Params_1       = Params ++ Boiler_plate_params,<br>    Req_params     = lists:flatten(string:join(lists:sort(Params_1), "&")),<br>    Rest_endpoint  = amazon_rest_endpoint(),<br>    Rest_path      = "/onca/xml",<br>    String_to_sign = [Method,        "\n",<br>                      Rest_endpoint, "\n",<br>                      Rest_path,     "\n",<br>                      Req_params],<br>    Signature = http_uri:encode(<br>                  base64:encode_to_string(<br>                    crypto:hmac(sha256, Secret_key, String_to_sign))),<br>    lists:flatten(["https://" ++ Rest_endpoint ++ Rest_path ++ "?",<br>                   Req_params,<br>                   "&Signature=", Signature]).<br><br>amazon_rest_endpoint() -> "<a href="http://webservices.amazon.co.uk">webservices.amazon.co.uk</a>".<br><br>aws_timestamp() -><br>    {{Y, M, D}, {H, Mi, S}} = calendar:universal_time(),<br>    lists:flatten(io_lib:format("~p-~s-~sT~s:~s:~sZ",<br>                                [Y, two_digits(M), two_digits(D),<br>                                 two_digits(H), two_digits(Mi), two_digits(S)])).<br></span><span style="font-family:monospace,monospace"><br>two_digits(X) when X < 10        -> [$0 | integer_to_list(X)]; <br>two_digits(X) when is_integer(X) -> integer_to_list(X);<br>two_digits([X])                  -> [$0, X];<br>two_digits(X)                    -> X.<br></span></font><br><br></div></div></div></div>