The answers to this question Is it okay for API secret to be stored in plain text or decrypt-able? are somewhat unsettling to me. I'm trying to wrap my mind around how storing a secret key in plaintext is in any way secure.
This is how I'm imagining an API access key / secret key based system to work:
- Client takes text of request and applies HMAC function with
secretKey
, resulting insignature
- Client adds
signature
andaccessKey
to request (effectively as authentication headers) and sends to server - Server extracts
accessKey
from request and looks up correspondingserverSecretKey
- Server takes text of request and applies HMAC function with server's version of
serverSecretKey
, resulting inserverSignature
- Server compares
signature
toserverSignature
; if they match, great, we're good - we know that the client has both a valid access key and a valid secret key
So before I go on, if the above is incorrect, then the rest of this question will more or less make no sense - so please let me know if the above understanding of API access/secret keys is valid or not :-)
Assuming my understanding is valid - my question comes back to how the secret key is stored - it has to be stored in plaintext for the above system to work.
So what happens if an attacker gains access to my database that has my all of my clients' API access keys and secret keys? Wouldn't they easily be able to use any access/secret key combination they like, and happily impersonate any client?
I'm looking at this from the perspective of bcrypt
-ed passwords. If an attacker gains access to a database with a whole bunch of bcrypt
-ed passwords, they have a whole lot of work ahead of them to make that database worthwhile to them, since brute forcing a set of bcrypt
-ed passwords is computationally expensive. That feels a whole lot more secure than storing secret API keys in plaintext in a database somewhere.
It seems like an API access key/secret key combination really only provides protection against tampering with a message (since the digital signature computed during steps #1 and #2 above is tied to the secret key) and doesn't really provide any assurance that the client is who they say they are. I don't see how it provides a level of security comparable to bcrypt
-ed passwords.
What am I missing here?