A Functional Approach to Web Services
One easy way to create API Keys is to use a cryptographic random number to
generate a difficult-to-predict key string. A small function, like the following,
should be good enough:
import random
rng= random.SystemRandom()
import base64
def make_key_1(rng=rng, size=1):
key_bytes= bytes(rng.randrange(0,256) for i in range(18*size))
key_string= base64.urlsafe_b64encode(key_bytes)
return key_string
We've used the random.SystemRandom class as the class for our secure random
number generator. This will seed the generator with the os.urandom() bytes, which
assures a reliably unpredictable seed value. We've created this object separately so
that it can be reused each time a key is requested. Best practice is to get a number of
keys from a generator using a single random seed.
Given some random bytes, we used a base 64 encoding to create a sequence of
characters. Using a multiple of three in the initial sequence of random bytes, we'll
avoid any trailing "=" signs in the base 64 encoding. We've used the URL safe base
64 encoding, which won't include the "/" or "+" characters in the resulting string,
characters that might be confusing if used as part of a URL or query string.
The more elaborate methods won't lead to more random data. The
use of random.SystemRandom assures that no one can counterfeit
a key assigned to another user. We're using 18×8 random bits,
giving us a large number of random keys.
How many random keys? Take a look at the following command and its output:
2*(188)
22300745198530623141535718272648361505980416
The odds of someone successfully forging a duplicate of someone else's key
are small.
Another choice is to use uuid.uuid4() to create a random Universally Unique
Identifier (UUID). This will be a 36-character string that has 32 hex digits and
four "-" punctuation marks. A random UUID is also difficult to forge. A UUID that
includes data such as username or host IP address is a bad idea because this encodes
information, which can be decoded and used to forge a key. The reason for using a
cryptographic random number generator is to avoid encoding any information.