Python has become a very popular language for software development. Over the decades since it was first introduced, the language has slowly grown and matured while keeping its ease of use and shallow learning curve. This has made it the go-to language for much of the AI and ML communities and many web applications have been built on Python. Many of these applications must use or manage user and API credentials such as passwords and API keys. Today, we will look at some of the methods used to store credentials in Python applications. Which method you choose depends on your specific requirements. My aim here isn’t to tell you which to use but instead, to introduce you to some of the methods in common use.
Hashing Passwords: One of the most secure ways to store passwords is by hashing them. Hashing is a one-way function that transforms plaintext passwords into a fixed-length string of characters. Python provides various hash functions such as SHA-256, SHA-384, and SHA-512, which can be used to generate a hash of the password. Once the password is hashed, it cannot be reversed to its original form, making it difficult for attackers to obtain the actual password. Here’s an example of hashing passwords in Python using the hashlib module:
Here’s an example of hashing passwords in Python using the hashlib module:
import hashlib password = "MyPassword123" salt = "abcd1234" # random salt value # add salt to the password salted_password = password.encode() + salt.encode() # generate hash of the salted password hashed_password = hashlib.sha256(salted_password).hexdigest() print(hashed_password)
Key Derivation Functions (KDFs)
Using Key Derivation Functions (KDFs): KDFs are designed to slow down the hashing process and make it more time-consuming, making it difficult for attackers to guess the password. The most common KDFs used in Python are PBKDF2 and bcrypt.
Here’s an example of using PBKDF2 in Python:
import hashlib import os from pbkdf2 import PBKDF2 password = "MyPassword123" salt = os.urandom(32) # generate a random salt value # generate a key using PBKDF2 key = PBKDF2(password, salt).read(32) print(key)
Encryption is another method of securing passwords in Python applications. In encryption, the password is encrypted using a key, which can be decrypted to obtain the original password. The most common encryption algorithms used in Python are AES, DES, and RSA.
Here’s an example of encrypting passwords in Python using the cryptography module:
from cryptography.fernet import Fernet password = "MyPassword123" # generate a key key = Fernet.generate_key() # create a Fernet object with the key fernet = Fernet(key) # encrypt the password encrypted_password = fernet.encrypt(password.encode()) print(encrypted_password)
Using a Password Manage
A password manager is a software application that stores and manages passwords for various online accounts. Password managers use encryption to store passwords, and users only need to remember one master password to access all their other passwords.
Python has several third-party password manager libraries, including LastPass and KeePass.
Storing Credentials in LastPass:
To use the LastPass Python library, you will need to install the
pip install lastpass
Here’s an example of how to store and retrieve credentials from LastPass:
import lastpass # create a new LastPass session vault = lastpass.Vault.open_remote('email@example.com', 'my_password') # create a new secure note in LastPass note = lastpass.SecureNote() note.name = 'my_note' note.set_field('username', 'my_username') note.set_field('password', 'my_password') # save the secure note to LastPass vault.add(note) # retrieve the secure note from LastPass note = vault.get_note_by_name('my_note') username = note.get_field('username') password = note.get_field('password') print(username, password)
Storing Credentials in KeePass
To use the KeePass Python library, you will need to install the
pip install pykeepass
Here’s an example of how to store and retrieve credentials from KeePass:
from pykeepass import PyKeePass # open KeePass database kp = PyKeePass('my_database.kdbx', password='my_password') # create new entry in KeePass database new_entry = kp.add_entry(kp.find_groups(name='my_group'), 'my_entry') new_entry.username = 'my_username' new_entry.password = 'my_password' # save changes to KeePass database kp.save() # retrieve entry from KeePass database entry = kp.find_entries(title='my_entry') username = entry.username password = entry.password print(username, password)
Storing Credentials in System Environment Variables
Storing credentials in system environment variables is another secure way of storing passwords in Python applications. Environment variables are values that are set in the operating system’s environment and are accessible to any program running in that environment. This method is useful when you need to share credentials across multiple applications running on the same system.
Here’s an example of setting and accessing environment variables in Python:
import os # set environment variable os.environ['DB_USERNAME'] = 'my_username' os.environ['DB_PASSWORD'] = 'my_password' # access environment variable db_username = os.environ.get('DB_USERNAME') db_password = os.environ.get('DB_PASSWORD') print(db_username, db_password)
Storing Credentials in a Virtual Environment
A virtual environment is a self-contained directory that contains all the necessary dependencies required by a Python application. Storing credentials in a virtual environment is a secure way of storing passwords because the credentials are only accessible by the application running in that environment.
Here’s an example of setting and accessing credentials in a virtual environment:
# create virtual environment python -m venv my_venv # activate virtual environment source my_venv/bin/activate # install dependencies pip install requests # set credentials as environment variables export API_KEY='my_api_key' export API_SECRET='my_api_secret' # access credentials in Python code import os api_key = os.environ.get('API_KEY') api_secret = os.environ.get('API_SECRET') print(api_key, api_secret)
Using password managers like LastPass and KeePass Python libraries can help you securely store and manage passwords in Python applications. These libraries provide an easy-to-use interface to access the password manager’s functionality and integrate it with your Python code. It’s essential to ensure that the password manager is configured correctly and that only authorized users have access to the password manager’s credentials.
Storing credentials in system environment variables and virtual environments is a secure way of storing passwords in Python applications. However, it’s essential to ensure that the credentials are encrypted or hashed before storing them in environment variables or virtual environments. It’s also important to limit the access of environment variables and virtual environments to authorized users to prevent unauthorized access to sensitive information.
When dealing with security concerns, care must be taken throughout a project to ensure that credentials are not leaked or inadvertently exposed through the development process. For example, many developers have accidentally committed sensitive information like passwords and API keys to a project’s repository. CI/CD pipelines can be used to help ensure that sensitive data is not leaked. A simple git hook on the developer’s machine can be used to ensure sensitive data is not committed to the repository.
I have seen API keys and passwords placed in a project’s documentation. While you may say this should never happen (and it shouldn’t), people are lazy (especially programmers) and often pressed for time, and that can lead to mistakes, shortsightedness, and errors. Keeping project documentation in the project’s repository and running pre-commit hooks to ensure that sensitive passwords and API keys are not committed to the project’s repository can greatly reduce if not eliminate these types of errors and improve security.