Whats the simplest and safest method to generate a API KEY and SECRET in Python

41,255

Solution 1

For python3.6+

import secrets

generated_key = secrets.token_urlsafe(length)

For older versions of python:

for a very secure way of generating random number, you should use urandom:

from binascii import hexlify

key = hexlify(os.urandom(length))

this will produce bytes, call key.decode() if you need a string

For general non-secure random strings, with more settings, you can just generate keys of your desired length the python way:

import random
import string

def generate_key(length):
    return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

And then you can just call it with your desired length key = generate_key(40).
You can specify what alphabet you want to use, for example using only string.ascii_lowercase for key consisting of only lowercase letters etc.

There is also Model for Api authentication in tastypie, might be worth checking out https://django-tastypie.readthedocs.org/en/latest/authentication.html#apikeyauthentication

Solution 2

If you're on Python 3.6 or later, the secrets module is the way to go:

The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.

In particular, secrets should be used in preference to the default pseudo-random number generator in the random module, which is designed for modelling and simulation, not security or cryptography.

e.g. to generate a 16 byte token:

>>> import secrets
>>> secrets.token_urlsafe(16)
'zs9XYCbTPKvux46UJckflw'
>>> secrets.token_hex(16)
'6bef18936ac12a9096e9fe7a8fe1f777'

Solution 3

you can also use following module to generate random string

 1 - os.urandom(64).encode('hex') #from os module
 2 - uuid.uuid4()                 # from uuid module
 3 - get_random_string(length=32) #from django.utils.crypto
 4 - secrets.token_hex(64)         #from secrets >= python 3.6 

Solution 4

Adding answer as I can't comment on T. Opletals answer.

You should not use random.choice as random isn't cryptographically secure. A better option would be random.SystemRandom() which uses the system source of randomness, on linux this would be urandom.

def generate_key(length):
    char_set = string.ascii_letters + string.punctuation                    
    urand = random.SystemRandom()                                           
    return ''.join([urand.choice(char_set) for _ in range(length)])
Share:
41,255
Dhanushka Amarakoon
Author by

Dhanushka Amarakoon

Updated on July 09, 2022

Comments

  • Dhanushka Amarakoon
    Dhanushka Amarakoon almost 2 years

    I need to generate a API key and Secret that would be stored in a Redis server. What would be the best way to generate a key and secret?

    I am develop a Django-tastypie framework based app.

  • Seán Hayes
    Seán Hayes over 8 years
    Not sure why this was downvoted, os.urandom() is both easy and the safest.
  • Paweł Mucha
    Paweł Mucha about 5 years
    Scroll down if you're using Python 3.6+. There is much simpler solution proposed by Moby Duck.
  • Paweł Mucha
    Paweł Mucha about 5 years
    Thanks! Here's a version to invoke straight from the terminal: python -c 'import secrets; print(secrets.token_urlsafe(16))'
  • user5305519
    user5305519 almost 4 years
    For Windows users running Pawel's code via cmd, if you get the error SyntaxError: EOL while scanning string literal, replace the single quotes with double quotes
  • lowercase00
    lowercase00 over 2 years
    Any inputs on the differences between token_urlsafe and token_hex? For which use case each one of those is recommended?
  • chrisinmtown
    chrisinmtown about 2 years
    It would probably be best to save in the database only a hash of a generated token, if it's not too far off topic, would you please recommend method(s) for computing a hash also?