简体   繁体   中英

HMAC Implementation for Web Service Authentication in PHP

I am trying to implement a web service and need some (very) simple Authenticate to restrict access to the service.

I found out about HMAC and I think I understand how to implement it. But I have a couple of questions in mind.

Let's say I have this HTML Form on the consumer side. When making a GET/POST request to my server.

  1. Is is enough to create a hash of: public_key using the secret_key ?
  2. OR, do I need to create a hash of the entire POST variables/array?

I'm thinking it would be enough to send the hash of the public_key only but just wanted to make sure and ask you guys.

I am planning to do this:

  1. Create a hash of the public_key
  2. Put the hash in a hidden field or in the URL as a param together with the public_key (or client_id) and other POST/GET variables.
  3. Receive on my server and verify the hash against the database by recreating the hash of the public_key using the secret_key .
  4. If the hash matches, I accept the POST/GET requests.

Your thoughts?

Clarification: public_key is like the client unique id where I can use to identify what secret key to use to generate the hash on the server.

The pubkey is just used as an alternative way to recognize the user. It could be the user email as well, by the way since you don't likely want to expose your user data to their programmer (or to potential sniffers) you create a unique identifier for each user. It's all it means. Then you need a private key to sign your hash.

Of course to make it worth it you have to sign all unique request data, otherwise someone could alter your request body and you wouldn't be able to detect it (MITM attack).

You also should care of creating a timestamp that must be included in the HMAC itself, then pass it alongside with the request. This way you can make the signature expirable and so you are not exposed to replay attacks (someone steals the request and without modifying it replies it against the server, operating multiple times the same action... think what a problem if it's a request to pay for your service, your user would be very very angry with you).

Also remember (nobody does) to encrypt also the Request-URI inside the HMAC itself and also the HTTP method (aka verb) if you're using a RESTful webservice, otherwise malicious users will be able to send the request to other URIs or (using RESTful services) change the meaning of your request, so a valid GET can become a potential DELETE. An example could be: user wants to see all its data, makes a GET request, a Man in the Middle reads the request and changes GET with DELETE. You are not given the opportunity to detect that something has been changed if it's not inside your HMAC you can check about, so you receive a DELETE request and boom! you destroy all user data.

So always remember: everything is essential to your request must be validable And if you rely on a HMAC then you must encrypt everything you need to trust the request.

Also always remember to start designing your system by denying all request, then if you can validate them perform requested actions. This way you always fall back on denied requests. It's better to have a user email telling you that he cannot do something that have your user data propagated on the net.

Use TLS. It fixes this and a host of problems you haven't even thought of yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM