Encryption in transit
TLS everywhere. Browser to server. Server to database. Service to service. Internal network too.
- TLS 1.2 or 1.3. Disable 1.0/1.1.
- Strong ciphers: AES-GCM, ChaCha20-Poly1305.
- HSTS to prevent downgrade.
- Automate certs with Let's Encrypt.
Encryption at rest
Database encryption: Cloud DBs support transparent encryption. Protects physical theft. Does not protect app-level access.
Application-level encryption: For SSNs, card numbers, health data - encrypt before storing. DBA or SQLi attacker sees only ciphertext.
from cryptography.fernet import Fernet
cipher = Fernet(key) # Key from secrets manager
encrypted = cipher.encrypt(data.encode())
Algorithm choices:
| Use case | Algorithm |
|---|---|
| Symmetric | AES-256-GCM |
| Asymmetric | RSA-OAEP 2048+ |
| Passwords | Argon2id, bcrypt |
Don't use: DES, RC4, MD5, SHA-1.
Key management: Never hardcode. Use KMS. Rotate periodically. Separate keys per purpose.
Password storage
Hash, don't encrypt. You should never need to reverse them.
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash(password)
ph.verify(hash, password)
Argon2id is recommended. bcrypt and scrypt are good. Never SHA-256/MD5.
Data minimisation
- Don't collect what you don't need.
- Define retention, automate deletion.
- Use anonymised data for analytics.
- Don't log passwords or tokens.
The takeaway
TLS everywhere. Encrypt sensitive data at rest. Hash passwords with Argon2id. KMS for keys. Minimise data collected.
