I'm building REST API that should be accesible for other developers. To authenticate clients I decided to use HMAC-SHA256 request signing with API key and secret key.
So the process of authentication looks like this:
- Along with the request body, client sends headers, containing his API key and signature generated using some data (request body/date/etc) +secret key
- Server receives requests and check if API key is valid and not revoked
- Server gets secret key from somewhere and generates signature by the same algorithm as client did
- If both signatures (received from client and generated on server) are the same, request is authenticated
Everything's here is very clear and simple. But the question is:where and how should I store that secret key and should it be the only one for all clients or different for each one of them.
I've read tons of articles, with lots of good examples of how to implement this kind of request authentication, but none of them tell how should I store secret key - in database, or in some document, located at server's FS. As I understood, both API key and secret key should not be encrypted. Because first one is used only for identifying or revoking client and second one should be fast accessible for server to create and compare signature.
And returning to the second part of question, should it be the only one secret key for all the users or private for each user? If it would be the only one key, it's simple to hide it on server, e.g. in environment variable. But what if it should be compromised on client's side? In this case I should change secret key and it will block my API for all of my other clients...
I found some information about security and effects of compromising here: Using HMAC-SHA1 for API authentication - how to store the client password securely?But still no useful information about storing.