I've been toying around with a simple application idea the last couple of days as I'm trying to teach myself the basic of REST authentication.
So far I've gathered that the best way to do this is with an implementation of HMAC like the one used by Amazon.
My biggest concern is with exactly how am I suppose to authenticate the user and give them their private key so they can begin signing the HMAC? I keep reading that the private key used for signing the HMAC is not supposed to be sent over the wire ever, but then how do they ever get it in the first place?
My idea was something like this, but I am not sure if this is valid.
Database table for users:
users (simplified, this would probably be a private key per client app?)
id (their public key?)
username
password?
privatekey
Assuming a HTML/JS client the user would be presented with a traditional login page that POST to the API with something like this:
https://example.com/myapp/api/v1/authenticate.json
POST: username / password
That would return either
404:User not found
200:{ "id" : <id>, "privatekey": <privatekey> }
The client would then store that key somewhere (would local storage/cookie be a safe place?) and use it to sign further requests that would look like this
GET https://example.com/myapp/api/v1/something/?key1=value1&publickey={theirID}&hmac={hmac signature of the request using their private key}
The server would then check the public key, retrieve the associated private key and rebuild the HMAC signature, if they match we have an authenticated request process it.
Am I getting this right? I'm not sure I understand the role of a private key if I still need a password like in my example so something is telling me that I might be wrong.
I think you need to provide more details about your application and how it will be used. There are many ways you can do REST authentication. Some of them are standard, some not. These are just some examples:
In case of Amazon S3, they give you "AWS secret access key" when you register. Later your application code needs to know secret key to be able to compute signatures (or it needs to know signed request/url) So ultimately "secret access key" is transmitted over the wire at least once initially during registration.
If you use public key cryptography (like client SSL certificates) - you can avoid transmitting private key altogether
If your goal is to just authenticate AJAX requests made to your site after user has authenticated on login page - you can simply use server signed cookies.