Spencer Ruport
Spencer Ruport

Reputation: 35117

Can't Mimic Amazon Web Services Signature Algorithm

I'm becoming extremely frustrated when people & companies don't provide reliable documentation for their products.

According to this site: http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

There is an algorithm that looks something like this:

import base64
import hmac
import sha
import urllib
h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV",
             "GET\n\n\n1141889120\n/quotes/nelson",
             sha)
urllib.quote_plus(base64.encodestring(h.digest()).strip())

Which should produce a result of:

vjbyPxybdZaNmGa%2ByT272YEAiv4%3D

I've tried several variations, different charsets and different languages and I cannot produce this hash. I even downloaded some samples and when I use their signing algorithms they still don't produce this hash. Here's the C# code I have:

    byte[] bytesToSign = Encoding.UTF8.GetBytes("GET\n\n\n1141889120\n/quotes/nelson");
    byte[] secretKeyBytes = Encoding.UTF8.GetBytes("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV");
    HMAC hmacSha256 = new HMACSHA256(secretKeyBytes);
    byte[] hashBytes = hmacSha256.ComputeHash(bytesToSign);
    string signature = Convert.ToBase64String(hashBytes);

But it produces a value of:

a5n2tpQTlqetX6Pjvv7vK23qi2JIZVlWZqIdteD2pok=

Yeah I can see that they're wrapping it with a URL encoder but that wouldn't change it this drastically. Does anyone have any idea what algorithm they may have used to produce this hash? I'm out of ideas.

Upvotes: 1

Views: 1470

Answers (1)

Justin Niessner
Justin Niessner

Reputation: 245489

Your C# code using the wrong HMAC hashing algorithm. From Amazon's documentation:

"The hash function to compute the signature is HMAC-SHA1 defined in RFC 2104 (http://www.ietf.org/rfc/rfc2104.txt), using your Secret Access Key as the key."

As it says, you need to use SHA-1 instead of SHA-256:

var bytesToSign = Encoding.UTF8.GetBytes("GET\n\n\n1141889120\n/quotes/nelson");
var secretKeyBytes = 
    Encoding.UTF8.GetBytes("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV");
var hmacSha1 = new HMACSHA1(secretKeyBytes);
var hashBytes = hmacSha256.ComputeHash(bytesToSign);
var signature = Convert.ToBase64String(hashBytes);

Upvotes: 2

Related Questions