Create and Manage Cryptographically Strong Tokens with Python for Better Web Application Security
Secret key management is a crucial aspect of a software engineer's daily routine. In this article, you will explore how to create and manage cryptographically secure keys in Python using the popular Pypi cryptography module. You will also learn the importance of securely storing these keys to ensure maximum protection of sensitive data in your web applications and software.
Prerequisites
You must install Python on your machine if you don't have it installed. It’s the only needed external requirement. You can install Python from their official downloads page. It’s recommended to install the latest version of Python for this tutorial.
To follow up with this tutorial, you are required to have some knowledge about writing simple Python programs. All the packages that will be discussed are from the Python standard library or Pypi package manager.
Secured Symmetrical Encryption Keys
When it comes to encryption and decryption in Python, the Pypi cryptography module is a popular choice. One of the easiest and most secure ways to implement symmetric cryptography using this module is through Fernet symmetrical encryption. However, to use Fernet keys for symmetric encryption, they must be generated and stored securely.
Let's dive in.
Start by creating a new Python project and set up your virtual environment to separate your project dependencies from your global dependencies.
python -m venv venv
# or
python3 -m venv venv
The Python command above is possible with Python3. If you have any errors setting this up, check out Python's official venv documentation to learn about creating a virtual environment.
- Activate the created environment
# Windows: cmd.exe
venv\Script\activate
# Linux: bash or Mac: zsh
source venv/bin/activate
Depending on your shell, the command for activating your virtual environment will be different. Check this reference for the command that will work for your shell.
- Now you need to install
cryptography
pip install cryptography
If you encounter any installation issues, you can check out its installation guide.
Enter the Python shell and run the following commands to generate the key.
>>> from cryptography.fernet import Fernet
>>> key = Fernet.generate_key()
b'RAuFlYBGswBmBOccV13UNYXxJTi19LCGhUOLZOi6oFY='
The value RAuFlYBGswBmBOccV13UNYXxJTi19LCGhUOLZOi6oFY=
in the byte string is the important key. It's stored like that because that's what the cryptography library likes to work with. So, if you generate a new key in the future, you need to convert it to bytes before passing it to any hash function.
Is Fernet.generate_key() cryptographically secure?
The answer is a resounding YES!
The implementation of Fernet.generate_key method uses the function os.urandom, which has more sufficient randomness than the random function from the built-in random module.
Why? It's because os.urandom cannot be seeded like random and draws its source of entropy from many unpredictable sources, making it more random. For more understanding, you can check this StackOverflow answer.
Now you can use your securely generated key to encrypt and decrypt data.
# Initialize a Fernet object
>>> f = Fernet(key)
# Generate a cryptographically secure and url-safe fernet token
>>> token = f.encrypt(b"Hashnode Neptune is the best")
>>> print(token)
b'gAAAAABkDv-R51WpztocZoMMat3UyKg8jz6KgCQgCq4g9SU36OF7kiPhqQwjLXPT-39lbb5cL-MlUWSmoDLKXlkOZo2Od_Icp_6jPFLDgF32f2r9agrRr50='
There you have it. You have generated a secure token that you can use to ensure your data security in your projects.
If you don't want to use the generate_key function to create your Fernet tokens. You can use this resource to generate a more secure and strong token using the PBKDF2HMAC algorithm.
Securely Managing Your Secret Keys
To ensure complete security, you must store your keys safely. Never share with anyone.
One easy way to do this is to use Pypi decouple.
- Let's start by installing it in our environment.
pip install python-decouple
- Create a file
.env
in your project directory. Add the key generated earlier to the file.
SECRET_KEY="RAuFlYBGswBmBOccV13UNYXxJTi19LCGhUOLZOi6oFY="
Save the file.
- Create a new Python program,
main.py
, in your project directory. Then paste the code added below into the file.
from decouple import config
SECRET_KEY = config('SECRET_KEY')
print(SECRET_KEY)
Run the main.py
python program.
python main.py
The secret key stored in the environment file would be displayed. Decouple is a project used to store the environment and secret keys. You can read more at Pypi Decouple.
What makes this approach better than using an operating system environment? Because it makes it easier to share secrets when collaborating with others. They only need to clone the project and copy the .env
file.
Also, it eliminates the collision of similar keys on multiple projects on the same machine. As a bonus, you can create a file env.example
, this file will contain the keys from the actual .env file but with fake values.
Your collaborator can then;
Create their
.env
file,Copy the contents of the
env.example
file into their.env
file,Generate a secret key,
Replace the sample (fake) key in the
.env
file with the newly generated key.
Ensure you don't forget to add
.env
file to.gitignore
so it doesn't get pushed to your GitHub repository, thereby exposing your keys. It's better to have a sample file likeenv.example
which can be pushed to keep track of what keys a collaborator needs to create when running the project on their machine.
Using Python Built-in Secrets Library
From Python Documentation: 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.
Use the Secrets library for security purposes to generate something random, like random tokens, digits, or strings. Its randomness is cryptographically secure.
Creating a secure hex token
- Run your Python shell.
>>> import secrets
>>> secrets.token_hex()
'20a3f7333abd0668e474d393870a0b47463a6935e2eb730343820767eaf77226'
That's a simple way to create a very secure token. The longer the token the more sufficient the randomness.
The function token_hex
accepts a parameter, n_bytes
, for how long you want the token.
>>> import secrets
>>> secrets.token_hex(64
'5222cffc8c2881afcbf219c90c6e2f3a8b168c7547f790c2e852a047e9f4c8094577d8198a1d802ee053d13987e9111b317a7771c9ce87597a67203311afc69f')
Read more in the Python Documentation
Now you can use generate highly secure tokens for your projects. These tokens can be used as a secret key in any project, Django, NodeJS, Golang, etc.
Conclusion
Securing web applications and software requires effective management of secret keys. Python offers libraries like cryptography and secrets that simplify the process of generating cryptographically secure tokens. To ensure maximum protection of sensitive data, it is crucial to store these keys securely using tools like Pypi Decouple and AWS Secrets Manager. By adhering to best practices for managing secret keys, developers can guarantee the security of their projects and prevent unauthorized access to sensitive information.
Read more
Follow me on Twitter @netrobeweb, Hashnode, and Dev.to where I post amazing projects and articles.
Thanks for reading, 🤓😊
Subscribe to my newsletter
Read articles from Ayomide Ayanwola directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Ayomide Ayanwola
Ayomide Ayanwola
Full stack developer | DevOps engineer | Cloud Technologist I develop software architectures for PaaS and SaaS startups and projects, deploy them on the cloud using serverless technology or Bare metal servers. I specialize in building software designs with Python, Golang and JavaScript.