Last month we found unencrypted API keys sitting in a client's database. Their excuse? "Encryption is too complicated." No, it isn't. Fernet encryption in Python takes four lines of code.
What Is Fernet?
Fernet is part of Python's cryptography library. It handles symmetric encryption - meaning you use the same key to encrypt and decrypt. But it's not just a thin wrapper around AES. There's real engineering behind it:
- AES-128 CBC for encryption
- HMAC-SHA256 for authentication
- Timestamp for time-based validation
That combination means Fernet doesn't just encrypt your data. It also guarantees the data hasn't been tampered with. If someone messes with the ciphertext, Fernet will catch it and refuse to decrypt.
Using Fernet in Python
First, install the library:
pip install cryptography
Then encrypt:
from cryptography.fernet import Fernet
# Generate a key (store this somewhere safe!)
key = Fernet.generate_key()
f = Fernet(key)
# Encrypt
message = "secret_api_key_12345"
encrypted = f.encrypt(message.encode())
# Decrypt
decrypted = f.decrypt(encrypted).decode()
print(decrypted) # secret_api_key_12345
That's it. Four lines for production-ready encryption.
Key Management - The Hard Part
Writing your Fernet key directly in your code is like locking your door and leaving the key under the mat. Don't.
Use environment variables:
import os
from cryptography.fernet import Fernet
key = os.environ.get('FERNET_KEY')
if not key:
raise ValueError("FERNET_KEY not set!")
f = Fernet(key.encode())
Or use a secret manager:
AWS Secrets Manager, HashiCorp Vault, Azure Key Vault - whatever you're already using. Pull the key from there, keep it in memory, never write it to disk.
Time-Limited Tokens with TTL
Fernet has a feature I really like: you can set a TTL (time-to-live) when decrypting.
from cryptography.fernet import Fernet, InvalidToken
f = Fernet(key)
token = f.encrypt(b"temporary_access_code")
# This token expires after 60 seconds
try:
result = f.decrypt(token, ttl=60)
except InvalidToken:
print("Token expired or invalid")
Perfect for temporary access tokens, password reset links, or one-time codes.
When Not to Use Fernet
Fernet isn't a silver bullet:
- Not for large files. Everything loads into memory. For gigabyte-sized files, you need streaming encryption.
- Not for asymmetric encryption. If someone needs to send you encrypted messages, you need a public/private key pair. Use RSA or ECC.
- Never for password hashing. Use bcrypt or Argon2 for passwords. Encryption is reversible, hashing isn't. Different tools for different jobs.
The Takeaway
Fernet kills the "encryption is hard" excuse. Four lines of code get you AES-128 encryption, HMAC authentication, and timestamp validation. Your only job is keeping the key safe.
Sensitive data in your database, API keys in config files, temporary tokens - none of these should exist as plaintext. Learn Fernet. Use it.