Code Reference

Encrypt

Python · Example / how-to

Encrypt

Python · Example / how-to


📋 Overview

Encrypt secrets at rest with modern cryptography—not homemade XOR. For passwords use one-way hashing (hashlib.scrypt / bcrypt). For reversible data use authenticated encryption (Fernet or AES-GCM via the cryptography package). Never commit keys; load from environment.

🔧 Core concepts

GoalApproach
Password storageSlow hash + salt (scrypt, argon2, bcrypt)
Symmetric encryptFernet (AES + HMAC) or AES-GCM
Key storageEnv var / secret manager—not source
IntegrityPrefer AEAD; detect tampering
Stdlib onlyhashlib, secrets, hmac—limited for full AEAD

Install: pip install cryptography

💡 Examples

Password hashing (stdlib scrypt):

import hashlib
import secrets

def hash_password(password: str) -> str:
    salt = secrets.token_bytes(16)
    digest = hashlib.scrypt(
        password.encode("utf-8"),
        salt=salt,
        n=2**14,
        r=8,
        p=1,
        dklen=32,
    )
    return f"{salt.hex()}${digest.hex()}"

def verify_password(password: str, stored: str) -> bool:
    salt_hex, digest_hex = stored.split("$", 1)
    salt = bytes.fromhex(salt_hex)
    digest = hashlib.scrypt(
        password.encode("utf-8"),
        salt=salt,
        n=2**14,
        r=8,
        p=1,
        dklen=32,
    )
    return secrets.compare_digest(digest.hex(), digest_hex)

if __name__ == "__main__":
    stored = hash_password("s3cret!")
    assert verify_password("s3cret!", stored)

Fernet encrypt / decrypt:

import os
from cryptography.fernet import Fernet

def get_fernet() -> Fernet:
    key = os.environ.get("APP_FERNET_KEY")
    if not key:
        # generate once: Fernet.generate_key().decode()
        raise RuntimeError("Set APP_FERNET_KEY")
    return Fernet(key.encode("utf-8") if isinstance(key, str) else key)

def encrypt_text(plain: str) -> bytes:
    return get_fernet().encrypt(plain.encode("utf-8"))

def decrypt_text(token: bytes) -> str:
    return get_fernet().decrypt(token).decode("utf-8")

if __name__ == "__main__":
    # Demo only — set a real key in production
    os.environ["APP_FERNET_KEY"] = Fernet.generate_key().decode()
    token = encrypt_text("hello")
    print(decrypt_text(token))

Generate a key once:

from cryptography.fernet import Fernet

print(Fernet.generate_key().decode())

⚠️ Pitfalls

  • MD5/SHA-1 alone are not password hashes—use scrypt/argon2/bcrypt.
  • Reusing IVs/nonces with AES-GCM is catastrophic; Fernet handles this for you.
  • Logging plaintext or keys defeats encryption.
  • hashlib.md5 for “checksums” is fine for non-security integrity only.

On this page