Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticating a Game Center player on an online game's servers

"Clash of Clans" uses Game Center to authenticate and link a player with an existing remotely stored game state.

From what I can see, a game is only provided a player identifier on client side. Is there a supported technique to securely authenticate a user instead of sending just the identifier (which is an equivalent of authenticating with just a username)?

like image 344
Ivan Vučica Avatar asked Jan 07 '13 18:01

Ivan Vučica


1 Answers

Since I asked the question, Apple has introduced a new API and the answer is available on: Setting up third-party server to interact with Game Center (thank you, user2949759) and on a few other places.

Specifically, since iOS 7 (Apple documentation on Wayback Machine):

-[GKLocalPlayer generateIdentityVerificationSignatureWithCompletionHandler:]

Generates a signature that allows a third party server to authenticate the local player.

The relevant callback block's arguments include NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp. These, along with player's playerID and bundleID, should be shipped off to the server as the 'login information'.

  • At this point, one should, server-side, use publicKeyURL to obtain the public key
  • serverside, verify that this public key has been signed by Apple
  • serverside, concatenate UTF-8-encoded playerID, bundleID, big-endian uint64 timestamp, and verbatim salt
  • serverside, generate SHA-256 of the above to produce digest
  • serverside, verify the signature that was shipped to the server is correct, using the public key downloaded earlier, the signature and the digest

There's an example in pseudo-PHP, an example of how one would implement this in Objective-C (which makes little sense to use verbatim), a Go implementation, a Ruby implementation and there is an assortment of implementations in other languages on that same question.

Unsurprisingly, the implementation in Go seems particularly readable, but it doesn't verify that the public key was issued by Apple. Linked Ruby implementation contains a rather clear example of how to do that.

like image 131
Ivan Vučica Avatar answered Oct 20 '22 08:10

Ivan Vučica