Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

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:

  1. Client takes text of request and applies HMAC function with secretKey, resulting in signature
  2. Client adds signature and accessKey to request (effectively as authentication headers) and sends to server
  3. Server extracts accessKey from request and looks up corresponding serverSecretKey
  4. Server takes text of request and applies HMAC function with server's version of serverSecretKey, resulting in serverSignature
  5. Server compares signature to serverSignature; 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?

share|improve this question
1  
For 15 minutes I've been trying to formulate an answer, but I'm not able to come up with anything better than the answers in the original question. They clearly describe why you can't hash API keys. I see nothing more to add. May I ask if you thoroughly read all of the answers? –  Adnan Jul 7 '13 at 15:08
    
Yes, I did. I still don't see how it's safe to store a secret key in plaintext in a database. If an attacker gets access to the database, it seems like it's game over, instantly. Am I mistaken on that? –  unforgiven3 Jul 7 '13 at 15:43
add comment

2 Answers

up vote 4 down vote accepted

Your thinking on this is too black and white: safe or unsafe. There's no safe here, just a spectrum of risk.

Companies that provide these APIs are making a judgement call and trying to balance risk with performance. Not all of these API calls need to happen over SSL. Think about uploading an image to S3, does it need to be encrypted? Probably not. The key requirement is that the calls are authenticated and authorized. Think about a million distinct calls to SDB or SQS, how much overhead on the client and server side will SSL create? Basically SHA2 is fast and SSL expensive, now multiply by 1,000,000.

Is there risk involved with keeping the API keys in plaintext on the server side? Certainly, but these companies are making a bet that they can put other mitigations around those key stores that lower risk to an acceptable level. (Ultimately if I get access to your key store, hashed or plaintext, there are several malicious things I can do like swap in my secret key for yours.)

About your statement: "doesn't really provide any assurance that the client is who they say they are"

That's true about almost all authentication schemes. If someone logs into this site with my username and password it doesn't prove that they are me, just that they possess my credentials. If someone uses my thumbprint to unlock a biometric lock, it indicates that they have some way of providing my thumbprint in a way the lock will accept it. What changes here is how difficult that is. Stealing credentials may not be that hard, impersonating thumbprints is probably harder but not impossible.

share|improve this answer
    
This makes sense; I can definitely understand what you mean here. Good point on swapping secret keys if you have access to the key store - didn't even think about that! –  unforgiven3 Jul 8 '13 at 21:58
add comment

In short it's not, however the secret key does not necessarily need to be stored in plaintext on the server. It could itself be encrypted (but not hashed as others have explained) with information that is part of a client request.

Similarly, if you login to a service that displays your secret keys, the keys need not have been stored in plaintext as they could be encrypted with a one way derivative of the password that was used to login, and which is kept associated with the session. While the secret key could be discovered given access to the session data, only a subset of client secret keys would be at risk at any one time.

share|improve this answer
    
That's an interesting thought (encrypting with a one way derivative). I think that helps for displaying secret keys to user (via an admin page or something like that), but it seems like it wouldn't help for general usage of the API, since the user's password wouldn't be used for non-login REST requests.. though I suppose that could be done. –  unforgiven3 Jul 7 '13 at 16:25
    
Exactly. When a user signs up for a service, they might provide a passphrase that they will subsequently use in their API requests, and the passphrase is used to encrypt any secret keys on the server. It's still game over for active API users if an intruder is now logging request data, but the damage is limited. –  Nick Jul 7 '13 at 16:33
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.