2

Looked on google and couldn't find anything.

Any good resources to get started designing my backend for a RESTless webapp thats going to rely heavily on API keys.

I know how to write restless webservices etc, just never used API-keys. Generally do people just generate guids for users etc?

Luke Belbina
  • 5,708
  • 12
  • 52
  • 75

2 Answers2

4

Here's how I'm creating API keys for a web service:

string CreateApiKey(int length)
{
    var bytes = new byte[length * 2];   
    using (var rng = new RNGCryptoServiceProvider()) 
        rng.GetBytes(bytes);
    var chars = Convert.ToBase64String(bytes)
        .Where(char.IsLetterOrDigit)
        .Take(length)
        .ToArray();
    var key = new String(chars);
    return key;
}
Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
2

GUID's are typically not "random" enough and can be easily guessed by the bad-guys.

Take some "random" data like the user's password hash, some random numbers and run the result through sha1 or a similar hash function.

If you want one API key per account, simply add it to the account metadata table. Otherwise use a table linked to the accountIds to store the api keys.

Server side use a cache using the api-key as the key to store temporarily the account metadata so you only need to go to the db once per session.

And of course everything must go over https to avoid that the API key be stolen.

Now if your service is "session" oriented you can consider using a temporary session key so you do not need to expose the API key. Look for public key encryption to investigate this further.

Peter Tillemans
  • 34,983
  • 11
  • 83
  • 114
  • "Guids are typically not random enough and can be easily guessed"? Not sure I agree with that at all. http://stackoverflow.com/questions/184869/are-guid-collisions-possible – toxaq Jan 17 '15 at 04:47
  • Part of the GUID are machine related, often IP or MAC address, the time of day, the address of the object generating the UID, a sequence counter. This makes it astronomically unlikely that the same ID is generated under normal use. However an attacker who WANTS to create a collision can use another GUID to determine the common bits and guess the 'changing' bits which are a relatively small subset which is much easier to brute force. Actually the answers in the question you refer to, illustrate this very nicely. – Peter Tillemans Jan 18 '15 at 15:13
  • I don't believe that's still true for UUID v4 though, which should be entirely 'random', and is what should be used. Is your hypothesis that a GUID is not suitable for an API key? – toxaq Jan 18 '15 at 21:41
  • Good point for UUID v4. It all depends on the use case. My concern is that although it looks like the API key has 128-bit 'security' in practice most of the bits in most of the UUID's can be 'guessed' quite accurately. If the attacker can make a lot of assumptions he can reduce the attack space considerably. Hashing them afterwards does not really reduce the number of possibilities, however you can't lift the bits from another key. – Peter Tillemans Jan 21 '15 at 09:38
  • But why bother : Ronnie shows you can easily create a random string and now the attacker needs to attack the RNG which is significantly harder. OTOH UUID's are probably Ok for securing 99% of API's, although again, why bother using something which was not made for that use-case. – Peter Tillemans Jan 21 '15 at 09:46
  • All good points. I've used v4 Uuids in a number of places due to their low collision probability and ubiquity. It's helpful if you want to tell the database to backfill a new column with a built in function (rather than writing code to repopulate it if you're using a custom RNG call). Thanks for the food for thought though, a helpful exercise. – toxaq Jan 21 '15 at 10:10