Key Takeaways

  • Symmetric: Same key encrypts/decrypts (AES)
  • Asymmetric: Public/private key pairs (RSA, ECC)
  • Hashing: One-way, fixed output (SHA-256)
  • Don't roll your own crypto - use libraries

1. Cryptography Fundamentals

Cryptography provides confidentiality, integrity, authentication, and non-repudiation. It's the foundation of secure communications, authentication, and data protection.

Core Concepts

2. Symmetric Encryption

Same Key for Encrypt/Decrypt

Fast, but key distribution is challenging.

# AES-256-GCM (recommended)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
nonce = os.urandom(12)

ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data)
plaintext = aesgcm.decrypt(nonce, ciphertext, associated_data)

Symmetric Algorithms

3. Asymmetric Encryption

# RSA key generation
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=4096
)
public_key = private_key.public_key()

# Encrypt with public key
ciphertext = public_key.encrypt(message, padding.OAEP(...))

# Decrypt with private key
plaintext = private_key.decrypt(ciphertext, padding.OAEP(...))

Asymmetric Algorithms

4. Hash Functions

# One-way functions - can't reverse
import hashlib

# SHA-256 (recommended)
hash = hashlib.sha256(b"message").hexdigest()

# For passwords, use slow hashes
import bcrypt
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
bcrypt.checkpw(password, hashed)

# Or Argon2 (winner of PHC)
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash(password)

5. Digital Signatures

# Sign with private key, verify with public key
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding

# Sign
signature = private_key.sign(
    message,
    padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
    hashes.SHA256()
)

# Verify
public_key.verify(signature, message, padding.PSS(...), hashes.SHA256())

6. PKI & Certificates

# X.509 certificate chain:
# Root CA → Intermediate CA → End-entity certificate

# Generate self-signed certificate (testing only)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

# View certificate
openssl x509 -in cert.pem -text -noout

# Verify certificate chain
openssl verify -CAfile ca-chain.pem certificate.pem

7. TLS/SSL Deep Dive

# TLS 1.3 handshake (simplified):
# 1. ClientHello (supported ciphers, key share)
# 2. ServerHello (chosen cipher, key share, certificate)
# 3. Encrypted communication begins

# Test TLS configuration
testssl.sh https://example.com

# Strong cipher configuration (nginx)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;

8. Cryptography Best Practices

FAQ

Is AES-256 breakable?
Not with current technology. AES-256 would require 2^256 operations to brute force - more than the atoms in the observable universe.

Crypto Attacks Password Cracking API Security