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.

Aren't API keys considered usernames and API secrets considered passwords? Why is it that API servers like Amazon Web Services allow you to view your API secret in plain text? It makes me think they store it in plain text or at least in a decrypt-able format.

Isn't it better if API secrets were treated as passwords that you should type-in to create then hashed in the database instead of being handed to you in plain text? If for some reason their API secret database were compromised it will easily open the flood gates for many applications that are using their API. However if it was hashed in a non decrypt-able manner then all is not easily lost.

share|improve this question
    
I have noticed this too (for AWS and every other API) and been curious. –  Feral Oink Aug 13 '12 at 0:07
1  
The short answer to your question is this: API secrets are symmetric keys, not passwords. What makes you think they don't store it in a decryptable format? –  David Schwartz Aug 13 '12 at 10:47
1  
@DavidSchwartz I didn't say that. I said it's either plain text or decrypt-able. –  IMB Aug 13 '12 at 11:28

4 Answers 4

Well in this backend you can also provision server and read all the data anyway. You need to make sure that nobody can access your backend, otherwise he will read all of your data at once including backups.

share|improve this answer

Whilst it would be more secure to hash the API tokens, it presents a usability problem: the tokens are long and random, and would have to be told to the user only once before hashing. This makes it a little difficult to secure them with a hash.

My suggestion for a secure scenario would be the following:

  1. Generate a random salt value and store it in the database. This salt must not be equal to the user's password salt.
  2. Take the user's plaintext password and compute KDF(password, salt), where KDF is a key-derivation function such as bcrypt. Call the resulting value k.
  3. Generate an API key.
  4. Encrypt the API key value with AES, using k as the key, and store the ciphertext in the database.
  5. Discard the plaintext API key and k.

When the user logs in, the webapp knows their password and uses it to compute k, which is then used to decrypt the API key and display it to them.

When the user wishes to use the API, they must send k as well as the plaintext API key, over SSL. The webapp can then decrypt the stored API key value using k and compare it to the given API key. If they match, it's valid. This allows API key use without the app needing to store the user's password.

If an attacker breaches the database, they must crack the user's password in order to compute k.

share|improve this answer
1  
And what in case of password change? –  Andrew Smith Aug 12 '12 at 23:51
    
Just a suggestion the unique salt can be anything from the user's password or something that remains constant like the userID. Point being, encryption better than plain text anyday. –  Rohan Durve - Decode141 Aug 13 '12 at 1:45
    
@AndrewSmith During password change the user should always be required to enter their existing password, to prevent walk-by attacks. This allows the computation of k. –  Polynomial Aug 13 '12 at 5:44
    
@RohanDurve-Decode141 In this case, yes, it could be the user ID. However, I normally give the advice to avoid using externally known values as salts in all cases, because the differences are subtle and things get complicated when dealing with password hashes. In this case, though, user ID is fine. –  Polynomial Aug 13 '12 at 5:46
    
Yeah, yeah! ...a missing part of the sentence caused that. I meant, "The answer is just a rough suggestion..." and was aimed at Mr. Smith. :) Ps. I didn't downvote. –  Rohan Durve - Decode141 Aug 13 '12 at 12:25

No. The API keys need to be stored in cleartext.

They are not passwords: they are cryptographic keys. These keys are used for things like authenticating requests (using SHA1-HMAC). The server needs to know the crypto key to apply the cryptographic algorithms.

Therefore, the API key needs to be stored in cleartext on the server. If the server stored only a hash of the API key, it could not verify the authenticity of messages from the client or authenticate messages sent to the client.

share|improve this answer
    
What is preventing an API server from hashing a key for storage since it can hash the user input (i.e., the client) for comparison the same way password storage works? –  IMB Aug 13 '12 at 11:31
2  
@IMB, If you hash the API key, and both sides use the hash of the API key as the actual cryptographic key (say, for use with a message authentication code), then you've gained nothing: the hash now becomes the effective key, and both sides are storing that in plaintext. The point is that a cryptographic key is not the same as a password. A password can be stored hashed; a cryptographic key generally cannot. –  D.W. Aug 13 '12 at 18:02
1  
@IMB, Amazon Web Services doesn't use HTTP Digest auth. And, HTTP Digest auth is insecure against a network attacker. Instead, Amazon Web Services uses a symmetric-key message authentication code to "sign" messages. That is more secure, but it requires a cleartext crypto key. –  D.W. Aug 13 '12 at 19:26
1  
@IMB, If you want to know about HTTP Digest auth over SSL, I'd encourage you to create a new question and ask about that one separately -- that's a different topic, and the answer for HTTP Digest auth over SSL is different from the answer for AWS. (Do note: HTTP Digest auth does not use an "API key".) –  D.W. Aug 13 '12 at 19:57
1  
@IMB, again, please move any questions about storage of the secrets for HTTP Digest Authentication to a separate question. Please avoid extended discussion of it in this comment thread. –  D.W. Aug 13 '12 at 20:09

Hashing is not storage; it irreversibly destroys data. We can get away with calling password hashing as "password storage" because when we actually need the password, we have a handy human operator to type it in. Indeed, when we hash the password we do not store the password, but only a token sufficient to verify the typed-in password.

An API key must be stored in such a way that it can be used again in an unattended fashion. The server must really store it, instead of just remembering a ghost of it, because it needs the genuine key to access the API.

share|improve this answer
1  
Is there any reason why an API server can't hash user input (i.e., hash the key)? And compare it to the hashed key stored in the server. Seems to me there's no special reason why keys can't be hashed. –  IMB Aug 13 '12 at 11:34
    
@IMB, see my response at the other place where you posted this same question. –  D.W. Aug 13 '12 at 18:04
    
@D.W., link, please? –  user359996 Feb 8 '13 at 20:34
    
@user359996, security.stackexchange.com/q/18572/971 –  D.W. Feb 8 '13 at 21:47

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.