Reputation: 4478
My Requirement
I am making a website which will have mobile version as well. So, I am making it API centric. Now I want to make my API secure without the complexities of OAuth because the security I need is quite simple. I don't want anyone with access to the api links to be able to access my data.
So, I came across this article http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/ which is quite amazing and cleared most of my doubts.
Right now, I am trying to recreate whatever is there in the article. I am using Laravel 5 framework for PHP for development.
I want to make sure that the API is being used by the mobile app and the web version only and no one else. I have seen api links like
example.com/fetchallinformation&publicKey=<something>&Hashkey?<some_hash_key>
Now, I understand that this key is generated by using hash_hmac()
function in php.
My Approach
My Confusion
I am not sure if this is the right way to do this.
Can we get the data that has been used to generate the hash using hash_hmac()
by decrypting the hash?
Upvotes: 5
Views: 2162
Reputation: 4903
I want to make sure that the API is being used by the mobile app and the web version only and no one else.
This is a problem that neither OAuth nor AWS-style signature authentication really help with. Both are about authenticating users, not applications. You can certainly implement either approach if you have a bunch of time to sink into it, but in both cases you're going to need to embed a "secret" in your apps, and once you give that app to a user your secret's not really a secret any more...
There's no great way to do what you're looking for. If someone's going to take the time to reverse-engineer your app to learn about how to directly hit the underlying API, anything else you do client-side to "authenticate" the calling application can be reverse-engineered as well.
I'd recommend not even bothering, and spending the time you save polishing your app so no one wants to bypass it and hit your API directly. :)
Upvotes: 0
Reputation: 179104
That HashKey in the URL is generated by hashing the privateKey and the publicKey in the client side and then sent to the server. So, i send the generated Hash along with the publicKey to the server.
Close, but not quite. As you just described it, a user with a given public key would send the same hmac with every request. That's no better than "username and password."
Side note: if you aren't using https, you're already insecure and whatever else you do to secure the site is of relatively little value.
The point of generating an hmac signature is that it not only authenticates the user as being in possession of the secret key, it also authenticates the specific request as being made by that user and being made during a specific window of time. Two different requests back to back should have a different hmac. One request today and an identical request tomorrow should also have a different hmac. Otherwise, you're in for replay attacks. This means information about the current time or expiration time of the signature, and information about the request itself, must be included in the information that's passed through the hmac algorithm or you're not accomplishing much.
For any given request, by a specific user, at a specific time, there can only be one possible valid signature. HMAC is not reversible, so you can't take the signature apart at the server end and figure out the attributes of the request.
Of course, of you're thinking about embedding that secret key in your app, remember that such tactics can be relatively trivial to reverse-engineer.
Is it a viable authentication mechanism? Of course. As the article points out, Amazon Web Services uses hmac signatures on their APIs, and they have a massive potential attack surface... but does that mean you will implement it in a meaningfully secure fashion? Not necessarily. There is always someone more clever, devious, and determined than you can imagine.
Even Amazon apparently realizes that their Signature Version 2 is not as strong as it could be, so they now have Signature Version 4, which has a much more complex algorithm, including several rounds of hashing and generation of an intermediate "Signing Key" that is derived from your secret, the current date, the specific AWS service, AWS region, and other attributes. Regions where Amazon S3 was first deployed in 2014 or later don't have support for the original Sig V2 at all -- and it seems like it can only be security-consciousness that drove that decision, since the old algorithm is computationally less expensive, by far.
Use caution in rolling your own security mechanisms.
If you are primarily trying to avoid the learning curve with OAuth, which I agree is quite annoying at first, you could be on a fool's errand.
Upvotes: 3
Reputation: 2459
If this method works for you it should definitely be fine, and undoubtedly it is secure.
Regarding decryption - HMAC is not supposed to be decrypted due to its nature (hash). HMAC is considered to be very secure and you should have no problems with it. You can read a bit more about How and when do I use HMAC? [SE Security]
Upvotes: 0