Question:
I am trying to use AWS API to create a stack in AWS CloudFormation, but they return error saying “signature we calculated does not match the signature you provided”
Fllowing is the code that I am using to generate the siganture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
$private_key = "xxxxxxxxxxxxx"; $params = array(); $method = "POST"; $host = "cloudformation.eu-west-1.amazonaws.com"; $uri = "/onca/xml"; // additional parameters $params["Service"] = "AWSCloudFormation"; $params["Operation"] = "DeleteStack"; $params["AWSAccessKeyId"] = "xxxxxxxxxxxxxx"; // GMT timestamp $params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z"); // API version $params["Version"] = "2010-05-15"; // sort the parameters // create the canonicalized query $canonicalized_query = array(); foreach ($params as $param => $value) { $param = str_replace("%7E", "~", rawurlencode($param)); $value = str_replace("%7E", "~", rawurlencode($value)); $canonicalized_query[] = $param . "=" . $value; } $canonicalized_query = implode("&", $canonicalized_query); // create the string to sign $string_to_sign = $method . "\n" . $host . "\n" . $uri . "\n" . $canonicalized_query; // calculate HMAC with SHA256 and base64-encoding $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $private_key, True)); // encode the signature for the request $signature = str_replace("%7E", "~", rawurlencode($signature)); the url I am using is 'https://cloudformation.us-east-1.amazonaws.com/ ?Action=DeleteStack &StackName=MyStack &Version=2010-05-15 &SignatureVersion=2 &Timestamp=2012-09-05T06:32:19Z &AWSAccessKeyId=[AccessKeyId] &Signature=[Signature] &SignatureMethod=HmacSHA256' |
Answer:
I confirmed Frederick’s answer. You must ksort the array before hashing it.