I have encountered this scenario a couple of times, but I hope to get confirmation that I am on the right track or a suggestion about what else should be done.
I am creating a back-end web service that provides access to confidential data or privileged operations. This web service will not be publicly accessible, but will be called by a front-end application that is. Ultimately, there may be multiple applications that need access to the service, but not necessarily with different levels of access.
We want to secure the web service so that any other device on the network can make calls to the service, or track traffic to determine how to authenticate.
Using a large and securely generated random API key, which is sent through basic authentication, the username and password are separated, the password is encrypted with SHA-256 and the result is compared with a value stored for the user.
Since the password is a large random value (say 128 bits), the purpose of encrypting the value is primarily:
- To avoid storing the API key in the web service
- To avoid synchronization attacks from string comparison against the real API key, if the application actually stored it
I thought about making a more typical password hash method (for example, Argon2), but since the password is not meant to be read by humans, it doesn't seem to get much. Even adding salt to the value does not seem to be very valuable since the space of possible API keys is very large.
There is also a clear need to keep this fast, as it will be sent with each request, so it is not convenient to do too much processing.
Also, since this method is very simple, I am not really looking for an alternative method if it is safe enough. I am really looking for improvements that can be made to this scheme or reasons why it is not absolutely certain (in which case I am willing to hear about alternatives).