Security Fundamentals & OWASP

Cryptography Essentials for Interviews

4 min read

Cryptography questions appear in almost every security interview. This lesson covers the concepts and comparisons you need to articulate clearly.

Symmetric vs Asymmetric Encryption

A classic interview question:

Aspect Symmetric Asymmetric
Keys Same key encrypts/decrypts Public/private key pair
Speed Fast Slow (100-1000x slower)
Key Distribution Challenge Public key can be shared
Use Cases Bulk data encryption Key exchange, signatures
Examples AES, ChaCha20 RSA, ECC, Ed25519

Interview Question

Q: "When would you use symmetric vs asymmetric encryption?"

Answer:

  • Asymmetric: Initial key exchange, digital signatures, TLS handshake
  • Symmetric: Encrypting the actual data after key exchange
  • Hybrid approach: TLS uses asymmetric to exchange symmetric session keys

Hashing vs Encryption

Aspect Hashing Encryption
Reversibility One-way (cannot recover input) Two-way (can decrypt)
Output size Fixed (e.g., SHA-256 = 256 bits) Variable (depends on input)
Use cases Password storage, integrity Data protection
Examples SHA-256, bcrypt AES-256-GCM
# Hashing (one-way)
import hashlib
hash_value = hashlib.sha256(b"data").hexdigest()

# Encryption (two-way)
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher = Fernet(key)
encrypted = cipher.encrypt(b"data")
decrypted = cipher.decrypt(encrypted)  # Can recover original

TLS/SSL Deep Dive

Interview favorite: "Explain the TLS handshake."

TLS 1.3 Handshake (Simplified)

Client                                Server
  |                                     |
  |-------- ClientHello --------------->|  (1) Supported versions, cipher suites
  |                                     |
  |<------- ServerHello ----------------|  (2) Chosen version, cipher suite
  |<------- Certificate ----------------|  (3) Server's certificate
  |<------- CertificateVerify ----------|  (4) Signature proving key ownership
  |<------- Finished -------------------|  (5) Handshake MAC
  |                                     |
  |-------- Finished ------------------>|  (6) Client handshake MAC
  |                                     |
  |<======= Application Data ==========>|  (7) Encrypted communication

Key Points for Interviews

  1. TLS 1.3 is current standard (TLS 1.2 still acceptable)
  2. 1-RTT handshake in TLS 1.3 (was 2-RTT in 1.2)
  3. 0-RTT resumption possible but has replay risks
  4. Perfect Forward Secrecy via ephemeral keys
  5. Certificate pinning prevents MITM with rogue CAs

Password Storage

Never store passwords in plaintext or simple hashes.

Algorithm Notes Parameters
Argon2id Winner of PHC, recommended Memory: 64MB, Iterations: 3, Parallelism: 4
bcrypt Widely supported Cost factor: 12+
scrypt Memory-hard N=2^14, r=8, p=1

Interview Code

# Modern password hashing with Argon2
from argon2 import PasswordHasher

ph = PasswordHasher(
    time_cost=3,          # Number of iterations
    memory_cost=65536,    # 64 MB memory usage
    parallelism=4,        # 4 parallel threads
    hash_len=32,          # Output length
    salt_len=16           # Salt length
)

# Hash password
hashed = ph.hash("user_password")

# Verify password
try:
    ph.verify(hashed, "user_password")
    # Password correct
except argon2.exceptions.VerifyMismatchError:
    # Password incorrect

Key Management

Interview Scenario: "Where would you store encryption keys?"

Key Storage Hierarchy

Level Solution Use Case
Development Environment variables Local testing only
Production Secrets Manager (AWS, Vault) Application secrets
High Security HSM (Hardware Security Module) Master keys, signing keys

Key Rotation

# Key rotation pattern
class KeyManager:
    def __init__(self, secrets_client):
        self.current_key_id = "key-v2"
        self.previous_key_ids = ["key-v1"]

    def encrypt(self, data):
        key = self.get_key(self.current_key_id)
        return encrypt_with_key(data, key, self.current_key_id)

    def decrypt(self, encrypted_data, key_id):
        # Support decryption with old keys during rotation
        if key_id == self.current_key_id or key_id in self.previous_key_ids:
            key = self.get_key(key_id)
            return decrypt_with_key(encrypted_data, key)
        raise KeyNotFoundError(f"Unknown key: {key_id}")

Quick Reference: Algorithm Selection

Purpose Recommended Avoid
Passwords Argon2id, bcrypt MD5, SHA1, SHA256
Data encryption AES-256-GCM DES, 3DES, ECB mode
Digital signatures Ed25519, ECDSA P-256 RSA < 2048 bits
Key derivation HKDF, PBKDF2 Simple hashing
Random numbers secrets module, /dev/urandom random module

Interview Tip: When asked about cryptography choices, always mention the specific algorithm AND parameters. "I'd use bcrypt" is okay; "I'd use bcrypt with a cost factor of 12 or higher" is much better.

In the next module, we'll cover application security including secure code review and threat modeling. :::

Quiz

Module 2: Security Fundamentals & OWASP

Take Quiz