6

I'm securing API calls to a REST service I'm building using API Keys. The plan is to:

  1. When we get a new client, generate an API Key (a UUID).
  2. Email the API key to them.
  3. They send the API key on every call to our service (over HTTPS). We will lookup the API Key in our database (either encrypting or hashing it first) and figure out the account the API key is for.

Eventually, we'll add user accounts and a portal for all this so clients can generate and deactivate API keys without us needing to be involved.

My question is on the last part. Should I hash or encrypt (or leave unecrypted?) the API keys before storing them in the database? I'm trying to understand the implications. I know that if I hash them, then I'm protecting against someone knowing all API keys if they get DB access. But what are the other things I should be thinking about? For example, are there performance reasons to do one over the other?

8

Yes, you should absolutely hash your API keys. In effect, they are your passwords and should be treated as such. And note that's hashed - not encrypted. You never need to decrypt the API keys, hence you should not be able to.

As saghaulor says, you need to make sure you use a version 4 UUID (a random one, that is) and that you use a cryptographically secure source of randomness when generating them. Since a correctly generated UUID contains 122 bits of entropy you need not worrie about salting or using a slow hash function like bcrypt. A single round of SHA-256 would be enough.

A problematic part of your design is that you are giving users "passwords" that are delivered by mail and that they can not change. That may not be good enough for security concious users. Perhaps the portal you mention will solve this problem.

|improve this answer|||||
  • I realize this is an old question, but how would they implement that portal safely? The only alternative I can think of would be displaying the API key for X minutes after creation, to allow the user to copy it somewhere safe. Otherwise they would have to persist it as plain text anyway, unless they also encrypted it. Correct? – s.m. Nov 15 '19 at 13:47
  • 1
    @s.m. Yes. Correct. – Anders Nov 15 '19 at 14:14
  • Oh wow, you replied! Thank you very much, very kind of you :) – s.m. Nov 15 '19 at 14:16
1

1) Make sure you're using a secure random generator to generate your UUID.

2) Do not email the API key. Email has no guarantee of secure transport, which is to say, you're likely sending the key in the clear.

3) How you implement the authentication mechanism will affect how you can store the API key.

If you're going to use the API key as a primary key, then you cannot hash or encrypt it as searching is effectively impossible if you hashed or encrypted correctly.

If what you provide the user is a combination of primary key and API key, you can then securely store the API key. Since the key is effectively a password, hashing should be sufficient and is recommended.

Remember to use the algorithm correctly. Generally, hashing requires a salt for each record. There are different hashing algorithms. Some, like bcrypt and scrypt can add artificial latency to slow down brute forcing. This may or may not be suitable for your use case. Some algorithms are not recommended, such as MD5 and SHA1 as they have been proven to be insecure.

You could hash the key without salt and then you can do simple searches. This will not be as secure as hashing with salt, but the security of said approach may be sufficient for your purposes.

|improve this answer|||||
  • So it sounds like if I have the API key as the primary key, I could hash without salt (making sure the hash doesn't collide with another key's hash) and store it. Then when I receive a request w/ API key, I hash it and look for a matching hash in the database. If I use a primary key and API key, then I can use a hash+salt because I can first lookup the salt by the primary key and compute the hash on the API key and see if they match. Am I understanding that correctly? Are there any recommended hashing algorithms that are fast and effective (considering this needs to be done on each request)? – Daniel Hipke Feb 23 '18 at 6:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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