11

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.

Alex W
  • 37,233
  • 13
  • 109
  • 109
jfrobishow
  • 2,897
  • 2
  • 27
  • 42

1 Answers1

13

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:

  1. Basic authentication over SSL
  2. Digest authentication
  3. Various kinds of token authentication (OAuth 2, SPNEGO, various STS)
  4. HMAC
  5. Client SSL Certificates
  6. Signed/encrypted cookies.

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

  1. you generate public/private key on client
  2. Submit public key to the server (or certificate signed by trusted authority)
  3. Sign requests(or nonces) with private key and server validates the signature using public key.

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.

LeopardSkinPillBoxHat
  • 28,915
  • 15
  • 75
  • 111
Sergey Zyuzin
  • 3,754
  • 1
  • 24
  • 17
  • The API is nothing but a little pet project of mine to teach myself something new. In that sense I was going to build the API first and then build the frontend as if I was an outsider. Instead of having direct call I was only going to use my API and require myself to use authentication, this way my own frontend would simply be consuming my API. When you say Amazon S3 gives you the private key at registration I think that's what I wasn't sure about, when do I give it to the 3rd party (or in this case give it to myself). OAuth 2 looks promising as well... – jfrobishow Jul 19 '13 at 03:22
  • I have a doubt.If the client is an externally accessible web application, the secret key (stored locally or in cookies) can be viewed from the underlying JS file by viewing the source. Right? How something like that be prevented? – Vinod Mohanan Oct 02 '15 at 17:30