Authenticating Key Issues

Community Platform API
Post Limit:
Wondering if any developers of other libraries that have received a public/private key to test with have many any verifiable progress? The process of building the authenticated header is pretty straight-forward, and I see a number of other libraries have built it in (C#, PHP, Java, etc.)...but I'm curious if any of those libraries have actually verified that their authenticated header works.

I've been working with a public/private key that Straton sent over and have been trying several dozen techniques on putting the authenticated request together and sending it over--all of which result in a "Invalid Application Signature". I have set up a test bed for him to help troubleshoot but as you might imagine, he's bogged down with his own work at present, and has little time to assist.

If you have a verified authenticated request working, shoot me a msg please...thanks!

07/30/2011 03:03 PMPosted by Mature
I've been working with a public/private key that Straton sent over and have been trying several dozen techniques on putting the authenticated request together and sending it over--all of which result in a "Invalid Application Signature". I have set up a test bed for him to help troubleshoot but as you might imagine, he's bogged down with his own work at present, and has little time to assist.


Does this mean you have a defined key? But haven't got it to work yet?
this is an example of my genauth function


public function genauth($url)
{
$UrlPath = $url;
$key = '';
$StringToSign = "GET \n" .date('D, d M Y G:i:s e') . "\n" . $UrlPath . "\n";

$Signature = base64_encode( HMAC-SHA1( utf8_encode( "my key goes here" ), $StringToSign ) );

$header = "Authorization: BNET ".$key.":".$Signature;
return $header;
}


note this is php code
Full code for PHP, with support for If-Modified-Since: lastModified
$url = "/api/wow/character/lothar/kelen";
$last_time_accessed = 0;//change to value of lastModified (for example 1312139101000) to get a blank page

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://us.battle.net" . $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);

date_default_timezone_set('GMT');
$request_date = date("D, d M Y G:i:s T");

$StringToSign = "GET" . "\n" . $request_date . "\n" . $url . "\n";

$private_key = "YourPrivateKey";
$public_key = "YourPublicKey";

$signature = base64_encode(hash_hmac('sha1', $StringToSign, $private_key, true));
$authorization = "BNET" . " " . $public_key . ":" . $signature;

if ($last_time_accessed > 0) {
$last_time_accessed = $last_time_accessed / 1000;
curl_setopt($ch, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
curl_setopt($ch, CURLOPT_TIMEVALUE, $last_time_accessed);
}

$header = array(
"Accept:",
"Date: " . $request_date,
"Authorization: " . $authorization
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

$f = curl_exec($ch);
curl_close($ch);
echo $f;
Do these work properly when the realm name has a quote in it and the character name has special characters? My signed requests seem to fail if I urlencode/rawurlencode a quote, but they also require urlencoding of special characters in a name.
I can't see what you are doing exactly, but you probably don't need to URL Encode or RAW Urlencode them at all. UTF-8 characters and Apostrophes are fine in URLs. Apostrophes only need to be encoded when written out to an HTML page where the apostrophe might interfere with attributes.

-Stephen
*EDIT* I assumed the people who posted code were the OP. I was mistaken. Nor were the people that posted code the same person.

I unfortunately don't have keys to test with yet, but your code seems to be fine. I only notice a few small differences from other code I've seen.

The date you use is different from other code. I've seen date(DATE_RFC2822) used instead of date("D, d M Y G:i:s T"). They produce two different strings:

Mon, 01 Aug 2011 15:07:05 -0400
Mon, 01 Aug 2011 15:07:05 EDT

Also in other code I've seen the "Accept:" portion of the header isn't sent, just Date and Authorization.

Again, I also don't know if what I'm suggesting works, I still can't test.
The date should be one of the following formats (as defined by the HTTP/1.1 protocol)

Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format

All 3 MUST be in GMT time. Obviously the top is the preferred format because it uses a 4 digit year and a timezone. The other 2 are older but servers are required to still allow them to be backwards compatible
here is my suggestion to blizzard for library developers. Library creators dont need 3000+ hits a day. What they need is something to let them know they implemented their HMAC correctly.

If there was an example private/public key with a date and the expected result it would be easy to test if someone implemented their code correctly. Given the same date and url, their code should produce the same hash and can be assumed to be working.

The keys dont even need to (and probably shouldnt) work on the website.

Maybe blizzard devs already thought of this?
If you're not sure your authentication code is working, try this tester:

http://everynothing.net/bnetauthtest.php

Make an authenticated request using the keys and URL supplied on that page and it'll return some debug information on whether your implementation is correct.
If you're not sure your authentication code is working, try this tester:

http://everynothing.net/bnetauthtest.php

Make an authenticated request using the keys and URL supplied on that page and it'll return some debug information on whether your implementation is correct.


Just a quick disclaimer that Blizzard can't ensure that third party authentication test services are accurate.

The quickest way to verify that an authenticated request works is to make an authenticated request and see if an error is returned.
Well yeah, if your auth routine works on battle.net, then you're good. :) But if you get back "Invalid authentication header" and you're not sure why, that tool may help.

No warranty expressed or implied, and if it breaks, you get to keep both pieces.
08/01/2011 06:43 PMPosted by Femor
If there was an example private/public key with a date and the expected result it would be easy to test if someone implemented their code correctly. Given the same date and url, their code should produce the same hash and can be assumed to be working.

short version (example private key):
$url = "/api/wow/character/lothar/kelen";
$request_date = Wed, 03 Aug 2011 13:52:48 GMT
$private_key = "1234567890ABCDEF";
expected signature: 1ppGP8nV5ciFyez3ZckXdnJYEWs=


long version: view php code above
If you're not sure your authentication code is working, try this tester:

http://everynothing.net/bnetauthtest.php

Make an authenticated request using the keys and URL supplied on that page and it'll return some debug information on whether your implementation is correct.


Thanks for this, it is a start--I'm at least verifying that I'm doing something wrong on my end, as this tool is also telling me the signature is incorrect.

And, with all do respect to Blizzard, I fully support the notion that we should be testing against Blizzard's servers--the only downside is that if it fails, there's no mechanism in place to describe why: (missing headers? date incorrectly formatted? signature incorrect? invalid keys, etc...), so any additional tools the community provides is of tremendous value.

I'm going to hammer away at it for a bit tonight and see what I determine...
08/03/2011 05:26 PMPosted by Mature
And, with all do respect to Blizzard, I fully support the notion that we should be testing against Blizzard's servers--the only downside is that if it fails, there's no mechanism in place to describe why: (missing headers? date incorrectly formatted? signature incorrect? invalid keys, etc...), so any additional tools the community provides is of tremendous value.


The API does indicate the difference between

  • Invalid or broken "Authorization" header
  • An invalid application key
  • An invalid signature
The API does indicate the difference between

  • An invalid signature


^^^ This..is the piece that requires a more detailed result to help us debug.

At present, there could be any number of reasons why the signature is invalid
- time exceeded XX seconds
- character set incorrect (ie. expected utf-8, got iso-8859-1)
- signature incorrectly encoded (ie. expected whitespace to come over as '+', got '%20' instead)

I'm currently up to about two dozen different iterations, all resulting in the same response "Invalid Application Signature"...which tells me nothing and forces me to resort to trial-and-error programming, which is an nightmare.
Has anyone run into issues where requests that have spaces in their URLs will throw an invalid signature error? I have it working for requests with no spaces. I've tried '%20' or '+' for spaces but I still receive the invalid signature error.
08/03/2011 06:52 PMPosted by Mature
- signature incorrectly encoded (ie. expected whitespace to come over as '+', got '%20' instead)


wait, spaces should be encoded as + in the header? But in the URL it wants them as %20...
did I misunderstand that?
so im guessing with a responce like
Array
(
[url] => http://US.battle.net/api/wow/guild/Zangarmarsh/Diverdaves%20Fan%20Club/?fields=members
[content_type] => application/json;charset=utf-8
[http_code] => 200
[header_size] => 223
[request_size] => 117
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 2.828
[namelookup_time] => 0
[connect_time] => 0.11
[pretransfer_time] => 0.11
[size_upload] => 0
[size_download] => 281099
[speed_download] => 99398
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0.406
[redirect_time] => 0
)

in my header code im not having any issues ...

Join the Conversation