2

I have been looking at techniques to secure an API for use in an android/iphone app or website application.
I have found one technique which I like but am unsure about if it is a good or what is wrong with it (aside from being a pritty long process).

Processing (users side initially):
First a salt is created by hashing the users password.
Then a signature is created by hashing the requested url (with username appended on the end via a query string) and the salt.
Lastly a token is created by hashing the username and the signature.
The token is passed inside a header to the server (everytime).

First Request:
The first request must be for the validate endpoint and include the device_id as a query string.
The same processing (as above) is done on the server and if the token matches that sent from the user than the device_id is stored in the database and is assigned to that username for future reference (the device id is found in the requested url) and is used to verify the username/device thereafter.

All subsequent requests:
The processing must take place on the users end and servers end for every request now with the token being different everytime (as the requested url changes).
No code is included as it is not written yet.

asked Jan 15, 2013 at 11:56
3
  • You don't 'create salt by hashing', you create hash with salt instead. Commented Jan 15, 2013 at 11:59
  • @JakubKonecki good point guess the salt should be a 'salt' and then hashed with the password. Commented Jan 15, 2013 at 12:02
  • a "salt" is just a secret bunch of random bytes added to passwords by the server before hashing the string. It protects against the same password (e.g. 'passw0rd') producing the same hash result everywhere. This prevents hackers from using rainbow tables to reverse the hash back to the password. Make your salt as obscure as you like, and you can even have a different salt value for each user name (but don't make it the user name, that's too obvious). Commented Jan 15, 2013 at 13:35

1 Answer 1

5

Your authentication model is a shared secret authentication. In your case your user's password serves as the shared secret. You need to ensure you have a secure way for getting the password to the user and server ahead of time. In order to sign the request you create a message with all your request headers and data. Then hash that request. Then that hash (token) will be passed with the request. The server will perform the same signing and hashing process on the server and ensure the tokens match.

In your example your sound like you want to create the token with this pseudo code:

Token = hmac-sha1( Hash(Pasword + Salt) + RequestUrl + UserName )

Your way is not bad but I would compare your method to Amazon's REST Auth model and implement a closer version of what they have detailed. http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

Their implementation:

"Authorization: AWS " + AWSAccessKeyId + ":" + base64(hmac-sha1(VERB + "\n" 
 + CONTENT-MD5 + "\n" 
 + CONTENT-TYPE + "\n" 
 + DATE + "\n" 
 + CanonicalizedAmzHeaders + "\n" 
 + CanonicalizedResource))

They have good reasons for including some fields that you have left out, including but not limited to:

  • The timestamp is to prevent replay attacks.
  • The content-MD5 is to prevent prevents people tampering with the request data (relevant to POST and PUTS)
answered Jan 15, 2013 at 14:51
1
  • 1
    Excellent. Also, if you need a simpler approach, you could just use Basic or Digest HTTP standard authentications through an SSL (HTTPS) connection. Commented Jan 15, 2013 at 15:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.