I am trying to get an implementation based on the AWS signed http request API to work between Erlang and PHP. But I can't get it to work.
The core approach is that you constructed a canonical version of an http request and sign it with a secret key and attach that signature to the headers.
On the Erlang side I am using crypto:sha/ which returns a 160 bit/20 byte signature - so I think that is SHA1
On the php side I am using hash_hmac/3 with the sha1 algo.
The Erlang code and output looks like this:
sign2(PrivateKey, Str) ->
io:format("Str is ~p~n", [Str]),
Sign = xmerl_ucs:to_utf8(Str),
io:format("Sign is ~p~n", [Sign]),
Hash = crypto:sha_mac(PrivateKey, Sign),
io:format("Hash is ~p~n", [Hash]),
binary_to_list(base64:encode(Hash)).
giving output of
Hash is <<147,121,203,238,1,247,248,246,157,133,49,21,159,146,41,243,124,101,99,57>>
B64 is "k3nL7gH3+PadhTEVn5Ip83xlYzk="
The PHP signing code is:
public function sign2($privateKey, $str) {
echo "privateKey is " . $privateKey . "\nstring is " . $str . "\n";
$hash = hash_hmac('sha1', $str, $privateKey, true);
$this->dump("hash ", $hash);
return base64_encode($hash);
}
Giving output of
privateKey is uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o
string is DELETE\n\n\n\nx-amz-date:Tue, 27 Mar 2007 21:20:26 +0000\n/johnsmith/photos/puppy.jpg
hash :217 254 129 103 14 29 63 36 176 253 241 183 51 111 120 22 117 125 167 104
Test hash_test1 fails expected: k3nL7gH3+PadhTEVn5Ip83xlYzk= got 2f6BZw4dPySw/fG3M294FnV9p2g=
This php implementation returns 160 bits/20 bytes which is why I think it ought to match crypto:sha from erlang - but I could be talking mince...
I suspect (from previous experience) that there is some mismatch between what I think hash_hmac is doing and what it actually is.