REST web service and API keys

2019-03-16 04:30发布

问题:

I have a web service I'm offering to users to tap into my applications database and get some info. Users have to register for an API key and provide that when making requests. Everything works fine but how do I check if the users who registered for a key is actually making the request and not somebody else who he might have given the key to?

I've been thinking for the last two days to come up with a solution but nothing so far.

回答1:

You need to use signed requests. Basically it works like that:

  • You give your user an API key and a "secret" (a random string) that only you and the client know.
  • Whenever they make a request, they add a "signature" parameter to it. This signature is basically a hash of the request parameters + the API key + other parameters (see below) + the secret.
  • Since you know the secret too, you can verify that the signature is correct.

To avoid replay attacks, you can also add nonces and timestamps into the mix. A nonce is simply a number that must be incremented by the client on each request. When you get the request, you check if you've already received this nonce/timestamp before. If you did, you reject the request (because it's most likely a replay attack). If not, you store the nonce/timestamp in your database so that you can look it up later on.

This is more or less how requests are signed in OAuth. Have a look at their example in the link.



回答2:

There are 2 parts to authenticating REST API calls. When a user registers with your service, you will typically assign a KEY identifying that user. Sometimes, this is enough. But this KEY can be shared, or stolen. In which case, your service will still consider the KEY to be valid. Now, in order to prevent key hijacks etc. you will also distribute a secret key. This key is never transported with the REST API request. This key is used to perform a one way hash of the API request, and create a signature (HMAC).

This signature, plus the API request (HTTP request in the form of URL) is then sent on to the API Server. The server performs the one way hash of the URL and compares with the signature using the private key of this user. If they match, it is "assumed" that the requester has access to the private key, and therefore the request is valid.

In order to avoid replay attacks, in addition to nonce (as suggested by the previous poster), you can also use hash chaining.