1

I am building a query to POST articles to the Apple News API and I am getting a WRONG_SIGNATURE response.

Apple instructs you to do the following:

  1. Create a canonical version of the request as a byte-wise concatenation of the following:

    The HTTP method (for example, GET or POST, in all caps)

    The full URL of the request

    The current date in ISO 8601 format

If the request is a POST request and it includes an entity, include the following:

The value of the Content-Type header

The full content of the entity

  1. Decode the API key’s secret from Base64 to raw bytes.

  2. Create the hash using HMAC SHA-256 over the canonical request with the decoded API key secret.

  3. Encode the hash with Base64.

  4. Set the Authorization header as:

    Authorization: HHMAC; key=; signature=; date= where is the date string from step 1.

  5. Send the request.

Here is my code that is returning the WRONG_SIGNATURE result (API credentials have been changed)

//set the timezone
date_default_timezone_set('UTC');

//get json to be sent
$data = file_get_contents('http://www.broadwayworld.com/articleapple.cfm?colid=195', true);

//set variables
$http_method = 'POST';
$date = gmdate('Y-m-d\TH:i:s\Z');
$key = '62a75411-dd-4c3b-9d9-c7053760';
$url = 'https://news-api.apple.com/channels/485ae91a-2212-4276-9d07-82da7/articles';
$secret = base64_decode('9w9sElVs4UVGxMkGxCWOOWHJknKiNWa6tA=');

//cannonical request
$canonical_request = $url . $http_method  . $date;

//Signature
$api_signature = base64_encode(hash_hmac('sha256', $canonical_request, $secret));

//curl options
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$headers = array();
$headers[] = "Authorization: HHMAC; key={$key}; signature={$api_signature}; date={$date}";
$headers[] = 'Content-Type: multipart/form-data';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

//get result
$server_output = curl_exec ($ch);
curl_close ($ch);
print  $server_output ;
Kara
  • 6,115
  • 16
  • 50
  • 57
Tom Canfarotta
  • 743
  • 1
  • 5
  • 14

4 Answers4

1

As it said in documentation

Create a canonical version of the request as a byte-wise concatenation of the following:`

  • The HTTP method (for example, GET or POST, in all caps)
  • The full URL of the request
  • The current date in ISO 8601 format

But in your code it is:

$canonical_request = $url . $http_method  . $date;

Change it to

$canonical_request = $http_method . $url  . $date;
Leigh
  • 28,765
  • 10
  • 55
  • 103
Denis Alimov
  • 2,861
  • 1
  • 18
  • 38
  • If the request is a POST request and it includes an entity, include the following: The value of the Content-Type header The full content of the entity so it should be `$canonical_request = $http_method . $url . $date . $content_type . $body;` see examples [https://developer.apple.com/library/ios/documentation/General/Conceptual/News_API_Ref/SecuritySampleCode.html#//apple_ref/doc/uid/TP40015409-CH8-SW1](here) – Denis Alimov Apr 27 '16 at 12:03
  • It doesn't make sense to use the body to create a key because the receiving server can not know what is being sent. This doesn't work either. – Tom Canfarotta Apr 27 '16 at 12:24
  • it is not the key, it is signature, you create a hash from all request content, then other side creates hash too and compare them. that is why you receive "Wrong Signature" response. Please read the docs again carefully, and examples too. You will see what you should do to successfully create article – Denis Alimov Apr 27 '16 at 12:52
  • if you still doubt that I am right, see how it is done here https://github.com/alleyinteractive/apple-news/blob/master/includes/apple-push-api/request/class-request.php for example – Denis Alimov Apr 28 '16 at 06:11
1

Tom, one thing you need to change in the hash_hmac is to add the true param to output raw. I found this by examining some Wordpress plugins that post to Apple News. I made this change in my code, which is essentially the same as yours, but I am still getting the WRONG_SIGNATURE too. $hash = hash_hmac('sha256', $canonical_request, $secret_key, true); So there is still something wrong, I can't spot it either.

CaymanCarver
  • 389
  • 3
  • 14
0

I was having the same issue, try removing the line:

$headers[] = 'Content-Type: multipart/form-data'; 

and check if that solves your problem!

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
-1

All of your steps are fine and ideally should work. Only check whether you creating the secret key by "GET" method and use "GET" method while posting the data. It works in my case.