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

"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)?

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.

Since you are authenticating with your own server, this is something between your client and your server to implement. Game Center won't be able to help you.
A simple idea would be to calculate a hash from the playerID using a function that only you know, and have the server compare it to what the client is sending.
Avoid generating a random key when your client runs for the first time, because when the client is re-installed, the user will be locked out.

Related

Where should I store my API key in IOS app [duplicate]

I want to store a secret key ("abc123") that I will use in the header of my REST API requests. My server will check this secret key. If it matches "abc123", then allow the request to be made.
I'm thinking about a simple solution like:
let secret = "abc123"
But are there going to be any downfalls to this?
Crazy as it sounds, this is probably the best solution. Everything else is more complicated, but not much more secure. Any fancy obfuscation techniques you use are just going to be reverse engineered almost as quickly as they'll find this key. But this static key solution, while wildly insecure, is nearly as secure than the other solutions while imposing nearly no extra complexity. I love it.
It will be broken almost immediately, but so will all the other solutions. So keep it simple.
The one thing that you really want to do here is use HTTPS and pin your certificates. And I'd pick a long, random key that isn't a word. Ideally, it should be a completely random string of bytes, stored as raw values (not characters) so that it doesn't stand out so obviously in your binary. If you want to get crazy, apply a SHA256 to it before sending it (so the actual key never shows up in your binary). Again, this is trivial to break, but it's easy, and won't waste a lot of time developing.
It is unlikely that any effort longer than an hour will be worth the trouble to implement this feature. If you want lots more on the topic, see Secure https encryption for iPhone app to webpage and its links.
By hardcoding the string in your app, it's possible for attackers to decrypt your binary (via tools like dumpdecrypt) and get your string without much trouble (a simple hexdump would include any strings in your app).
There are a few workarounds for this. You could implement an endpoint on your REST API which returns your credentials, that you could then call on launch. Of course, this has its own non-trivial security concerns, and requires an extra HTTP call. I usually wouldn't do it this way.
Another option is to obfuscate the secret key somehow. By doing that, attackers won't be able to instantly recognize your key after decryption. cocoapods-keys is one option which uses this method.
There's no perfect solution here – the best you can do is make it as difficult as possible for an attacker to get a hold of your keys.
(Also, be sure to use HTTPS when sending requests, otherwise that's another good way to compromise your keys.)
While in-band tokens are commonly used for some schemes, you're probably eventually going to implement TLS to protect the network traffic and the tokens. This as Rob Napier mentions in another reply.
Using your own certificate chain here allows the use of existing TLS security and authentication mechanisms and the iOS keychain, and also gives you the option of revoking TLS credentials if (when?) that becomes necessary, and also allows the client to pin its connections to your servers and detect server spoofing if that becomes necessary.
Your own certificate authority and your own certificate chain is free, and your own certificates are — once you get the root certificate loaded into the client — are just as secure as commercially-purchased certificates.
In short, this certificate-based approach combines encryption and authentication, using the existing TLS mechanisms.
It looks like you are using access tokens. I would use Keychain for access tokens. For Client IDs, I would just keep them as a variable because client ids don't change while access tokens change per user, or even per refresh token and keychain is a safe place to store user credentials.
I have used the PFConfig object (a dictionary) that allows you to retrieve in your app values of variables stored as Server environment parameters.
Similar to the environment variables that can be retrieved using ENV in web sites server side programming like Ruby or PHP.
In my opinion this is about as secure as using Environment variables in Ruby or similar.
PFConfig.getConfigInBackgroundWithBlock{
(config: PFConfig?, error: NSError?) -> Void in
if error == nil {
if let mySecret = config["mySecret"] as? String {
// myFunction(mySecret)
}
}

Swift protect hard coded string for privacy [duplicate]

I want to store a secret key ("abc123") that I will use in the header of my REST API requests. My server will check this secret key. If it matches "abc123", then allow the request to be made.
I'm thinking about a simple solution like:
let secret = "abc123"
But are there going to be any downfalls to this?
Crazy as it sounds, this is probably the best solution. Everything else is more complicated, but not much more secure. Any fancy obfuscation techniques you use are just going to be reverse engineered almost as quickly as they'll find this key. But this static key solution, while wildly insecure, is nearly as secure than the other solutions while imposing nearly no extra complexity. I love it.
It will be broken almost immediately, but so will all the other solutions. So keep it simple.
The one thing that you really want to do here is use HTTPS and pin your certificates. And I'd pick a long, random key that isn't a word. Ideally, it should be a completely random string of bytes, stored as raw values (not characters) so that it doesn't stand out so obviously in your binary. If you want to get crazy, apply a SHA256 to it before sending it (so the actual key never shows up in your binary). Again, this is trivial to break, but it's easy, and won't waste a lot of time developing.
It is unlikely that any effort longer than an hour will be worth the trouble to implement this feature. If you want lots more on the topic, see Secure https encryption for iPhone app to webpage and its links.
By hardcoding the string in your app, it's possible for attackers to decrypt your binary (via tools like dumpdecrypt) and get your string without much trouble (a simple hexdump would include any strings in your app).
There are a few workarounds for this. You could implement an endpoint on your REST API which returns your credentials, that you could then call on launch. Of course, this has its own non-trivial security concerns, and requires an extra HTTP call. I usually wouldn't do it this way.
Another option is to obfuscate the secret key somehow. By doing that, attackers won't be able to instantly recognize your key after decryption. cocoapods-keys is one option which uses this method.
There's no perfect solution here – the best you can do is make it as difficult as possible for an attacker to get a hold of your keys.
(Also, be sure to use HTTPS when sending requests, otherwise that's another good way to compromise your keys.)
While in-band tokens are commonly used for some schemes, you're probably eventually going to implement TLS to protect the network traffic and the tokens. This as Rob Napier mentions in another reply.
Using your own certificate chain here allows the use of existing TLS security and authentication mechanisms and the iOS keychain, and also gives you the option of revoking TLS credentials if (when?) that becomes necessary, and also allows the client to pin its connections to your servers and detect server spoofing if that becomes necessary.
Your own certificate authority and your own certificate chain is free, and your own certificates are — once you get the root certificate loaded into the client — are just as secure as commercially-purchased certificates.
In short, this certificate-based approach combines encryption and authentication, using the existing TLS mechanisms.
It looks like you are using access tokens. I would use Keychain for access tokens. For Client IDs, I would just keep them as a variable because client ids don't change while access tokens change per user, or even per refresh token and keychain is a safe place to store user credentials.
I have used the PFConfig object (a dictionary) that allows you to retrieve in your app values of variables stored as Server environment parameters.
Similar to the environment variables that can be retrieved using ENV in web sites server side programming like Ruby or PHP.
In my opinion this is about as secure as using Environment variables in Ruby or similar.
PFConfig.getConfigInBackgroundWithBlock{
(config: PFConfig?, error: NSError?) -> Void in
if error == nil {
if let mySecret = config["mySecret"] as? String {
// myFunction(mySecret)
}
}

How to save a string safely in iOS?

I must save a string (a passphrase) in the keychain but the original string:
doesn't come from the server;
is not generated by the user;
it must be compared on a server (I send it over https);
So, the string must live somewhere in the app (hardcoded?).
I'm quite sure you can't prepare data for the keychain to be readily available for the app after it is installed, like you can just add a plist to the app bundle so that it can be loaded right away if the app is running (even if it's the first time it gets launched).
I have read about Data Protection: it allows applications that work with sensitive data to take advantage of encryption available on some devices. Is that the way to go? That is: I store my data into a text file, then I protect the file, then I retrieve my data from the file, then I save it to the keychain?
Any tip is appreciated.
If it is not possible to provide the string from outside (user input, a server) developer is forced to put it in the application bundle in some form. It can be hardcoded, stored in a file, or generated by a function. It means application has all necessary information to get/produce such a string. Thus it is not able to secure the information as good as encryption would do.
iOS apps are protected by Apple's DRM, so you can feel safe if someone copies your binary to Mac and starts disassembling it. However, if hacker has a jailbroken device there are tools to dump your application binary from memory to disk, unfortunately.
So it boils down to obfuscation. You could write a function that generates the string dynamically (e.g. a series of operations on hardcoded array of bytes and then convert it to the string). This will make your string harder to intercept by the hacker.
As main concern is with paraphrase or access token, it can be saved as encrypted data in keychain but this will be decrypted whenever we will send a request & it can be tracked on jailbroken devices.But using more agnostic algos to encrypt request data will increase API response time.However defining user based permissions at server side is best way as in worst case only 1 user's data can be tracked.
SSL Pinning - using challenge response authentication, we can prevent app from man in the middle attack. Yes, ssl pinning can be bypassed but it's not that easy & only possible on jailbroken devices.
Defining expiry time to few seconds could be another way to prevent user's data.Identifying source of request is also very important before granting permissions..
So by collaborating multiple ways we can try to make better system.
EDIT
Generally we encrypt data using 1 key as token & it can be decrypted once that key is revealed.
Asymmetric Encryption adds 1 more layer of encryption using public & private keys.
https://developer.apple.com/library/content/documentation/Security/Conceptual/Security_Overview/CryptographicServices/CryptographicServices.html#//apple_ref/doc/uid/TP30000976-CH3-SW12
here is one more example where random salt is used over token to encode data https://en.wikipedia.org/wiki/PBKDF2
Variants of this question have been discussed on SO a bunch of times already, and unfortunately you won't find a perfect answer, as there isn't one.
Essentially, you want to ship authentication credentials in your app, i.e. you bundle a secret into it. This means that no matter what you do, there's a possibility that an attacker retrieves it via reverse engineering. Even if you encrypt it with a hard algorithm that is technically secure enough, at some point your app decrypts it and since the app might be in the hands of an attacker, they will be able to sniff the secret.
This means in the end you can only try to make it hard for them by basically obfuscating the way in which you handle the secret ("make sniffing complicated"). Bundling an encrypted file that gets decrypted and then packed into the keychain seems not like a bad idea to me for a start, but keep in mind that for somebody looking at your app, especially on a jailbroken iPhone, this vanishing file can be a good first hint. Also, deleting it doesn't really help, as one re-install easily restores it.
Another idea could be to use On-Demand Resources to distribute your secret, this might also make it easier to replace it with an updated version in case your secret gets compromised. I am not that familiar with on-demand resources myself, though, so I can't tell you how suited they would be for actually revoking things.
This all assumes that you have no way of implementing an authentication mechanism based on user input. That way an attacker could only steal their own password (assuming they don't steal someone else's iPhone...) and not a vital part of your entire app (which could potentially affect all users).
Other SO answers from my bookmarks that might help you are these:
https://stackoverflow.com/a/9183066/710041
https://stackoverflow.com/a/9448821/710041
Okay, after re-reading your last comment under the question again, here's a concrete suggestion. I don't know why you need this second password/token at all if you're already having user authentication (you talk about them logging in), but here you go:
You don't bundle a token/pass together with the app at all. When first running your app, user's have to log in anyways (if I got you right), so your server can be involved and this is where you start.
During this login, the server generates a token/password and will send this to the user (depending on your exact implementation/custom protocol this might be done in a second request/response done by the app that uses the same user credentials or you put it into the headers of the response to the very first request sent by the app). Note that you don't need to encrypt this as long as you use https, as this already encrypts this data. So the channel by which your token arrives within your app is secure.
The app then saves this token/pass in the keychain immediately. This is as good encrypted as it gets on a mobile device. Do not save the token in anything else, even temporarily. The pass only ever exists in plain when it's in memory (you can't avoid that).
You use that token for whatever you need it (I am actually wondering why you need it if you're already using https and a user login system at all).
All in all this sounds like a pretty standard pseudo-OAuth-like token approach, if you're just wanting to use the token to avoid always relying on the user credentials (username and password) in each request. Technically you could also just save username and password in the keychain and always get those for each request. Usually these tokens have a limited time-to-live after which they become invalid anyways and the app has to rely on username and password again to get a new one anyways.
The potential downside of a token is if it's static and not user-bound or if it doesn't have this time-to-live limit. You would have to generate this in a clever way on the server and obviously note which user uses which token. That way you can pinpoint security breaches and react accordingly (instead of suddenly shutting down the server for all users by invalidating your one and only token). Again, I don't see why you need this, though.
Regarding a man-in-the-middle attack: A token, be it app-bundled (which is a risk in itself) or server generated, doesn't in itself protect against that. I have no idea what your boss would aim for here, but perhaps I'm missing some information. In general, https already protects you from this (well, usually only the server is authenticated, but if you already have a username and password system, you should be fine for the client side, too). It's actually a big point of it in general. To me this sounds more and more like something in your original problem is simply a misunderstanding of the existing infrastructure and/or a "boss-induced" problem... :)
What you can do is have your parameters encrypted using AES 256 encryption while calling an API, then the server decrypts the parameters and again sends encrypted response.You can decrypt and read the response, provided your server and app shares the same key used for encryption and decryption.
I had a similar functionality in my app so my Util class encrypts and decrypts the request and response using the following code,
class func encrypt (stringToEncrypt: String) -> String {
let messageData = stringToEncrypt.data(using: .utf8)
let encryptedBytes = try! AES(key: "abcdefghijklmnopqrstuvwxyz012345", iv: "abcdefghijklmost").encrypt([UInt8](messageData!))
return encryptedBytes.toBase64()!
}
class func decrypt ( message: String) -> String {
let messageData = Data(base64Encoded: message, options: .ignoreUnknownCharacters)
let decryptedBytes: [UInt8] = try! AES(key: "abcdefghijklmnopqrstuvwxyz012345", iv: "abcdefghijklmost").decrypt([UInt8](messageData!))
let unencryptedString = String(bytes: decryptedBytes, encoding: .utf8)
return unencryptedString!
}
Again this is just a suggestion you can do it using other ways also.
For saving some string values in Keychain you can make use of a pod library
pod 'SSKeychain'
You can save a string to keychain as follows
let appName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
SSKeychain.setAccessibilityType(kSecAttrAccessibleAlways)
SSKeychain.setPassword(stringToSave, forService: appName, account: "MyAppName")
Also retrieve the same using
let appName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
let stringRetrieved = SSKeychain.passwordForService(appName, account: "MyAppName")
Import these once you installed the above pod
import SystemConfiguration
import SSKeychain
This will be retained even if the app the deleted and re-installed. If you want additional encryption you can make use of any encryption algorithm this one is useful
AES encryption in swift
Encryption techniques may help to get solve the requirement. Here is the simple elaboration how we can maintain a keys on top of the Diffie–Hellman key exchange encryption techniques.
Prerequisites:
Maintain public and private key pairs on both the sides client and server.
Algorithm or logic to generate private keys should use same for both client and server end.
Logic to break the final acquire keys to compare the own string.
Process:
Both app and backend should have a common public key what ever it is in this case just take it as application name like MyApplication.
public key: MyApplication
Should generate private keys on the both the ends by using some encryption process or logic. For suppose generate random number as private key like below.
Suppose App private key is: 10
Suppose Backend private key is: 90
Generate exchange keys on both app and backend by following some kind of algorithm. Here just to combine both public and private keys like
App final key: MyApplication + 10
Backend final key: MyApplication + 90
Exchange the keys in between app and backend.
App Got key: MyApplication + 90
Backend Got key: MyApplication + 10
Compare the received key with own by using some kind of technique like
i. Generated new App key by combining app private key and App Got key like: MyApplication + 90 + 10
ii. Generated new Backend key by combining Backend private key and Backend Got key like: MyApplication + 10 + 90
To Check both the key are same need follow to logic For example here Just add last two number in the keys result will be like
App owned key: MyApplication + 100
App acquired key: MyApplication + 100
BackEnd owned key: MyApplication + 100
BackEnd acquired key: MyApplication + 100
Hola finally both backend and app has the same key.
Depends on the requirements needs maintain different private key per each session and store it on keychains. or make one private key and store it on app side.
NOTE: This description illustrates just an overview how to maintain the keys, It may involves lot of logics and also has a provision to break up the keys by others that totally depends on encryptions and logics using to generate and break the keys.
References:
https://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange
https://security.stackexchange.com/questions/7390/how-to-properly-encrypt-a-communication-channel-between-a-client-and-a-server-w

Setting up third-party server to interact with Game Center

I'm thinking of adding a feature to my iOS game to allow players to create their own game levels, share them with other players, rate them, etc. There'd be a public repository of user-created levels, sortable by creation date, rating, difficulty, or other criteria.
This kind of functionality would necessitate a third-party server. I was thinking I'd create a RESTful API using Sinatra and run it on Heroku. My question is: what would be the best way to authenticate requests to this API? I would prefer not to require players to create a username and password. I'd like to just use Game Center's ID system.
Any suggestions? I've never done any server-side stuff before so any help is appreciated!
Clarification
Yes, I'm aware that Apple doesn't provide its own system. But it does give developers access to unique Game Center identifiers (developer.apple.com/library/mac/#documentation/…) and I was hoping I could use that somehow to roll my own authentication system without requiring users to sign on via Facebook/Twitter/etc. If that's possible.
Looks like as of iOS 7, this is possible with Game Center using:
[localPlayer generateIdentityVerificationSignatureWithCompletionHandler]
Once you have verified the identity of the player using the generateIdentity call,
Associate the player id with a user on your server's db
Use whatever access token / authentication pattern your REST framework provides for subsequent calls
https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html
Also for reference, here is the dictionary that we end up sending off to our server based on the response from generateIdentityVerificationSignatureWithCompletionHandler
NSDictionary *paramsDict = #{
#"publicKeyUrl":[publicKeyUrl absoluteString],
#"timestamp":[NSString stringWithFormat:#"%llu", timestamp],
#"signature":[signature base64EncodedStringWithOptions:0],
#"salt":[salt base64EncodedStringWithOptions:0],
#"playerID":localPlayer.playerID,
#"bundleID":[[NSBundle mainBundle] bundleIdentifier]
};
edit: as if when I posted this there was no official solution from Apple, but there is now. See the other answers for that, or read on purely for historical / backwards-compatibility interest.
Apple doesn't provide any sort of system for using Apple ID authentication (which includes Game Center) with third-party services. You're on your own for authentication, though you could look into OAuth for allowing single-sign-on via Facebook/Twitter/etc. (Just beware that not everyone has a Facebook/Twitter/etc identity, or one that they want to use for your game.)
In theory, the playerID property on GKPlayer is unique, constant, and not known to anyone else. So, in theory, you could use it for "poor man's authentication": present it to your server, and that's all the server needs to look up and provide player-specific stuff. But this is like authentication by UDID, or by user name only -- the only security it provides is obscurity. And what happens when you have a user who's not signed into Game Center?
Andy's answer is on the right track, but to finish the story: in those docs that he links to, there's an explanation of how to actually authenticate against Apple services that the GameCenter user actually is who he is claiming to be. Link to that part of the docs is below. Basically, the call on the client to generateIdentityVerificationSignatureWithCompletionHandler gives your some data including a URL. You give that data and the URL to your own server, and then from your server you can hit that URL to authenticate the user with the rest of the data that was provided by the call to generateIdentityVerificationSignatureWithCompletionHandler.
https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/index.html#//apple_ref/occ/instm/GKLocalPlayer/generateIdentityVerificationSignatureWithCompletionHandler:
I had a heck of a time figuring this out. I finally used a few hints from this answer, a couple of other SO answers, the php docs and some lucky guessing to come up with this complete answer.
NOTE: This method seems very open to hacking, as anyone could sign whatever they want with their own certificate then pass the server the data, signature and URL to their certificate and get back a "that's a valid GameCenter login" answer so, while this code "works" in the sense that it implements the GC algorithm, the algorithm itself seems flawed. Ideally, we would also check that the certificate came from a trusted source. Extra-paranoia to check that it is Apple's Game Center certificate would be good, too.

Implementing a 2 Legged OAuth Provider

I'm trying to find my way around the OAuth spec, its requirements and any implementations I can find and, so far, it really seems like more trouble than its worth because I'm having trouble finding a single resource that pulls it all together. Or maybe it's just that I'm looking for something more specialized than most tutorials.
I have a set of existing APIs--some in Java, some in PHP--that I now need to secure and, for a number of reasons, OAuth seems like the right way to go. Unfortunately, my inability to track down the right resources to help me get a provider up and running is challenging that theory. Since most of this will be system-to-system API usage, I'll need to implement a 2-legged provider. With that in mind...
Does anyone know of any good tutorials for implementing a 2-legged OAuth provider with PHP?
Given that I have securable APIs in 2 languages, do I need to implement a provider in both or is there a way to create the provider as a "front controller" that I can funnel all requests through?
When securing PHP services, for example, do I have to secure each API individually by including the requisite provider resources on each?
Thanks for your help.
Rob, not sure where you landed on this but wanted to add my 2 cents in case anyone else ran across this question.
I more or less had the same question a few months ago and hearing about "OAuth" for the better part of a year. I was developing a REST API I needed to secure so I started reading about OAuth... and then my eyes started to roll backwards in my head.
I probably gave it a good solid day or 2 of skimming and reading until I decided, much like you, that OAuth was confusing garbage and just gave up on it.
So then I started researching ways to secure APIs in general and started to get a better grasp on ways to do that. The most popular way seemed to be sending requests to the API along with a checksum of the entire message (encoded with a secret that only you and the server know) that the server can use to decide if the message had been tampered with on it's way from the client, like so:
Client sends /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad
Server gets all that, looks up user "123" in database, loads his secret key and then (using the same method the client used) re-calculates it's OWN checksum given the request arguments.
If the server's generated checksum and the client's sent checksum match up, the request is OK and executed, if not, it is considered tampered with and rejected.
The checksum is called an HMAC and if you want a good example of this, it is what Amazon Web Services uses (they call the argument 'signature' not 'checksum' though).
So given that one of the key components of this to work is that the client and server have to generate the HMAC in the same fashion (otherwise they won't match), there have to be rules on HOW to combine all the arguments... then I suddenly understood all that "natural byte-ordering of parameters" crap from OAuth... it was just defining the rules for how to generate the signature because it needed to.
Another point is that every param you include in the HMAC generation is a value that then can't be tampered with when you send the request.
So if you just encode the URI stem as the signature, for example:
/user.json == askJdla9/kjdas+Askj2l8add
then the only thing in your message that cannot be tampered with is the URI, all of the arguments can be tampered with because they aren't part of the "checksum" value that the server will re-calculate.
Alternatively, even if you include EVERY param in the calculation, you still run the risk of "replay attacks" where a malicious middle man or evesdropped can intercept an API call and just keep resending it to the server over and over again.
You can fix that by adding a timestamp (always use UTC) in the HMAC calculation as well.
REMINDER: Since the server needs to calculate the same HMAC, you have to send along any value you use in the calculation EXCEPT YOUR SECRET KEY (OAuth calls it a consumer_secret I think). So if you add timestamp, make sure you send a timestamp param along with your request.
If you want to make the API secure from replay attacks, you can use a nonce value (it's a 1-time use value the server generates, gives to the client, the client uses it in the HMAC, sends back the request, the server confirms and then marks that nonce value as "used" in the DB and never lets another request use it again).
NOTE: 'nonce' are a really exact way to solve the "replay attack" problem -- timestamps are great, but because computers don't always have in-sync timestamp values, you have to allow an acceptable window on the server side of how "old" a request might be (say 10 mins, 30 mins, 1hr.... Amazon uses 15mins) before we accept or reject it. In this scenario your API is technically vulnerable during the entire window of time.
I think nonce values are great, but should only need to be used in APIs that are critical they keep their integrity. In my API, I didn't need it, but it would be trivial to add later if users demanded it... I would literally just need to add a "nonce" table in my DB, expose a new API to clients like:
/nonce.json
and then when they send that back to me in the HMAC calculation, I would need to check the DB to make sure it had never been used before and once used, mark it as such in the DB so if a request EVER came in again with that same nonce I would reject it.
Summary
Anyway, to make a long story short, everything I just described is basically what is known as "2-legged OAuth". There isn't that added step of flowing to the authority (Twitter, Facebook, Google, whatever) to authorize the client, that step is removed and instead the server implicitly trusts the client IF the HMAC's they are sending match up. That means the client has the right secret_key and is signing it's messages with it, so the server trusts it.
If you start looking around online, this seems to be the preferred method for securing API methods now-adays, or something like it. Amazon almost exactly uses this method except they use a slightly different combination method for their parameters before signing the whole thing to generate the HMAC.
If you are interested I wrote up this entire journey and thought-process as I was learning it. That might help provide a guided thinking tour of this process.
I would take a step back and think about what a properly authenticated client is going to be sending you.
Can you store the keys and credentials in a common database which is accessible from both sets of services, and just implement the OAuth provider in one language? When the user sends in a request to a service (PHP or Java) you then check against the common store. When the user is setting up the OAuth client then you do all of that through either a PHP or Java app (your preference), and store the credentials in the common DB.
There are some Oauth providers written in other languages that you might want to take a look at:
PHP - http://term.ie/oauth/example/ (see bottom of page)
Ruby - http://github.com/mojodna/sample-oauth-provider
.NET http://blog.bittercoder.com/PermaLink,guid,0d080a15-b412-48cf-b0d4-e842b25e3813.aspx

Resources