Skip to content

Cryptography

Cryptography is the mathematical science of securing communication and data. It is not a security Solution by itself — it is a tool that, when correctly applied within a secure system, provides Confidentiality, integrity, authentication, and non-repudiation.

PrimitivePurposeExamples
Symmetric encryptionConfidentiality (high-speed)AES, ChaCha20
Asymmetric encryptionConfidentiality (key exchange)RSA, ECIES
Hash functionsIntegrity, password storageSHA-256, SHA-3, bcrypt
Message authenticationIntegrity + authenticityHMAC, Poly1305
Digital signaturesNon-repudiation, authenticityRSA-PSS, ECDSA, EdDSA
Key exchangeSecure shared secret establishmentDiffie-Hellman, ECDH
Random number generationKey material, nonces, salts/dev/urandomCSPRNG

A cryptosystem should be secure even if everything about the system, except the key, is public Knowledge. This means:

  • The algorithm is published and peer-reviewed
  • Security depends only on key secrecy
  • The algorithm works even if the attacker has full knowledge of its implementation

This is why rolling your own crypto is almost always wrong. AES has been studied for decades by Thousands of cryptanalysts. Your custom cipher has been studied by nobody.

Symmetric encryption uses the same key for encryption and decryption. It is fast (orders of Magnitude faster than asymmetric encryption) and is the standard for bulk data encryption.

AES is a block cipher selected by NIST in 2001 (FIPS 197) as the successor to DES. It operates on 128-bit blocks with key sizes of 128, 192, or 256 bits.

ParameterAES-128AES-192AES-256
Key size128 bits192 bits256 bits
Rounds101214
Security128-bit192-bit256-bit
PerformanceFastestModerateSlightly slower

AES is a substitution-permutation network (SPN). Each round applies:

  1. SubBytes: Non-linear byte substitution using an S-box
  2. ShiftRows: Cyclic permutation of bytes within each row
  3. MixColumns: Linear transformation mixing each column
  4. AddRoundKey: XOR with the round key derived from the key schedule

A block cipher operating on 128-bit blocks needs a mode of operation to handle messages longer than One block. The mode determines how blocks are chained together and how ciphertext is produced.

Each block is encrypted independently with the same key.

Block 1 + Key → Ciphertext Block 1
Block 2 + Key → Ciphertext Block 2
Block 3 + Key → Ciphertext Block 3

Do not use ECB. Identical plaintext blocks produce identical ciphertext blocks, revealing Patterns in the data. The classic demonstration is encrypting an image — ECB preserves visual Structure completely.

Each plaintext block is XORed with the previous ciphertext block before encryption. An Initialization vector (IV) is used for the first block.

IV + Block 1 → XOR → Encrypt → Ciphertext Block 1
Ciphertext Block 1 + Block 2 → XOR → Encrypt → Ciphertext Block 2

CBC requires:

  • IV must be unpredictable (random, not a counter). Reusing an IV with the same key is catastrophic.
  • Padding ( PKCS#7) to align plaintext to block boundaries.
  • Decryption is parallelizable; encryption is sequential.

Vulnerability: CBC is vulnerable to padding oracle attacks if the system leaks information about Whether padding is valid. The BEAST attack (2011) exploited CBC in TLS 1.0 where the IV was the last Ciphertext block of the previous record.

CTR turns a block cipher into a stream cipher. A counter value is encrypted to produce a keystream, Which is XORed with the plaintext.

Counter 0 + Key → Encrypt → Keystream Block 0 → XOR → Plaintext Block 0 → Ciphertext Block 0
Counter 1 + Key → Encrypt → Keystream Block 1 → XOR → Plaintext Block 1 → Ciphertext Block 1

CTR properties:

  • No padding required: It is a stream cipher mode, so plaintext can be any length.
  • Fully parallelizable: Both encryption and decryption can be parallelized.
  • Random access: Any block can be decrypted independently.
  • Nonce requirements: The counter value must never repeat for the same key. A nonce (96 bits) combined with a block counter (32 bits) is standard (NIST SP 800-38A).

Vulnerability: CTR provides confidentiality only. It provides no integrity. If an attacker flips A bit in the ciphertext, the corresponding plaintext bit is flipped and the modification is Undetectable. Always combine with a MAC.

GCM combines CTR mode encryption with Galois field authentication, providing both confidentiality And integrity (AEAD — Authenticated Encryption with Associated Data).

Plaintext → CTR Encryption → Ciphertext
Ciphertext + Associated Data → GHASH → Authentication Tag
Output: Ciphertext + Tag

GCM properties:

  • AEAD: Confidentiality + integrity in a single operation.
  • Associated data: Can authenticate metadata (headers, nonces) without encrypting it.
  • Performance: Hardware-accelerated AES-GCM is extremely fast (AES-NI instruction set).
  • Tag length: 128 bits (16 bytes). Shorter tags (96, 64 bits) reduce security margin.

Prefer Curve25519 and Ed25519 over NIST P-256/P-384 for new systems. The NIST curves have parameter Generation that was not fully transparent (though no backdoor has been found), and Curve25519/Ed25519 have simpler, faster implementations with fewer side-channel risks.

Diffie-Hellman (DH) allows two parties to establish a shared secret over an insecure channel without Transmitting the secret itself.

  1. Alice and Bob agree on a prime pp and generator gg (public parameters)
  2. Alice generates private key aaSends A=gamodpA = g^a \mod p
  3. Bob generates private key bbSends B=gbmodpB = g^b \mod p
  4. Alice computes s=Bamodps = B^a \mod p
  5. Bob computes s=Abmodps = A^b \mod p
  6. Both arrive at the same shared secret s=gabmodps = g^{ab} \mod p

An eavesdropper who sees AA and BB cannot compute ss without solving the discrete logarithm Problem.

Same principle as FFDHE but over an elliptic curve group. ECDH with Curve25519 (X25519) is the Standard for modern key exchange:

// Go example: ECDH key exchange
privateKey, _ := x25519.GenerateKey(rand.Reader)
publicKey := privateKey.Public()
// sharedSecret is the same on both sides
sharedSecret, _ := privateKey.ECDH(peerPublicKey)

Forward secrecy (also called perfect forward secrecy, PFS) ensures that compromise of a long-term Key does not compromise past session keys. If you use RSA to encrypt a symmetric key and the RSA Private key is later compromised, all past sessions can be decrypted.

With ephemeral Diffie-Hellman (DHE or ECDHE), the key exchange uses temporary key pairs that are Discarded after the session. Even if the server’s long-term key is compromised, past sessions remain Secure.

A cryptographic hash function maps arbitrary-length input to a fixed-length output with the Following properties:

  1. Preimage resistance: Given hash hhIt is infeasible to find mm such that \mathrm{Hash(m) = h
  2. Second preimage resistance: Given m1m_1It is infeasible to find m2m1m_2 \neq m_1 such that \mathrm{Hash(m_1) = \mathrm{Hash(m_2)
  3. Collision resistance: It is infeasible to find any pair m1m2m_1 \neq m_2 such that \mathrm{Hash(m_1) = \mathrm{Hash(m_2)
AlgorithmOutput SizeBlock SizeRoundsStatus
SHA-1160 bits512 bits80Broken (collision found, 2017)
SHA-224224 bits512 bits64Secure
SHA-256256 bits512 bits64Secure
SHA-384384 bits1024 bits80Secure
SHA-512512 bits1024 bits80Secure
SHA-3-256256 bits1088 bits24Secure (Keccak)

SHA-3 was selected by NIST in 2012 as a backup to SHA-2. It uses a different internal structure (sponge construction vs Merkle-Damgard in SHA-2), so an attack on SHA-2 would not necessarily affect SHA-3.

SHA-3 is not faster than SHA-2 in software, but it is significantly faster in hardware (FPGA/ASIC Implementations). Use SHA-3 when you want algorithmic diversity or are implementing in hardware.

Standard hash functions (SHA-256, SHA-3) are not suitable for password hashing. They are Designed to be fast, which makes them vulnerable to brute-force and dictionary attacks with GPUs.

Password hashing functions are designed to be slow and memory-hard, making brute-force attacks Expensive.

  • Design: Blowfish-based, adaptive cost parameter
  • Salt: 128-bit random salt embedded in output
  • Cost factor: 2^{\mathrm{cost} iterations (default 10 = 1024 iterations, recommended 12+)
  • Output: 60 characters (e.g., $2b$12$R9h/cIPz0gi...)
import bcrypt
# Hash a password (cost factor 12)
password = b"correct_horse_battery_staple"
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
# Verify
bcrypt.checkpw(password, hashed) # True
bcrypt.checkpw(b"wrong", hashed) # False

Limitation: bcrypt has a 72-byte password length limit. Passwords longer than 72 bytes are Silently truncated. Pre-hashing with SHA-256 before bcrypt mitigates this.

  • Design: Memory-hard, CPU-hard
  • Parameters: Cost (CPU/memory), block size (memory), parallelization
  • Advantage over bcrypt: Resistant to GPU/ASIC attacks due to memory requirements
import hashlib
# scrypt hash (Python 3.6+)
salt = b"random_salt_16_bytes"
hashed = hashlib.scrypt(
b"password",
salt=salt,
n=2**14, # CPU/memory cost
r=8, # block size
p=1, # parallelization
dklen=64 # output length
)

Argon2 is the winner of the Password Hashing Competition (2015) and is recommended by OWASP for new Applications.

VariantResistance TargetUse Case
Argon2idGPU + side-channelRecommended default
Argon2iSide-channelThreat model includes side-channel attacks
Argon2dGPUThreat model excludes side-channel attacks
from argon2 import PasswordHasher
ph = PasswordHasher(
time_cost=3, # number of iterations
memory_cost=65536, # 64 MB
parallelism=4, # number of threads
hash_len=32, # output length
salt_len=16 # salt length
)
hashed = ph.hash("correct_horse_battery_staple")
ph.verify(hashed, "correct_horse_battery_staple") # True

OWASP recommended parameters (2023):

ParameterArgon2idscryptbcrypt
Memory64 MB (65536)N/AN/A
Iterations3N/A10+
Parallelism41N/A
Salt length16 bytes16 bytes16 bytes (embedded)
Hash length32 bytes32 bytes31 characters

A MAC provides integrity and authenticity for a message. The sender and receiver share a secret key.

HMAC (Hash-based MAC, RFC 2104) uses a cryptographic hash function with a secret key:

\mathrm{HMAC(K, m) = H\Big((K' \oplus \mathrm{opad) \;\|\; H\big((K' \oplus \mathrm{ipad) \;\|\; m\big)\Big)

Where KK' is the key padded to the block size, \mathrm{opad = \mathrm{0x5c...And \mathrm{ipad = \mathrm{0x36....

import hmac
import hashlib
key = b"secret_key"
message = b"important message"
mac = hmac.new(key, message, hashlib.sha256).hexdigest()
# Verify: hmac.compare_digest(mac, received_mac)

The “harvest now, decrypt later” threat is real. Attackers may be recording encrypted traffic today To decrypt it when quantum computers become available. Organizations with long-term confidentiality Requirements (government, healthcare, financial) should begin PQC migration planning now.

ECB encrypts each block independently, preserving patterns in the data. Never use ECB. If you need a Mode without authentication, use CTR. If you need both confidentiality and integrity, use GCM or ChaCha20-Poly1305.

Keys in source code, configuration files committed to Git, or environment variables in CI logs are Immediately compromised. Use a dedicated secret management system (HashiCorp Vault, AWS KMS, Azure Key Vault).

Pitfall 3: Using SHA-256 for Password Hashing

Section titled “Pitfall 3: Using SHA-256 for Password Hashing”

SHA-256 is designed to be fast. An attacker with a modern GPU can compute billions of SHA-256 hashes Per second. Use bcrypt (cost 12+), scrypt, or Argon2id for password storage.

In GCM mode, nonce reuse is catastrophic — it enables both forgeries and plaintext recovery. In CTR Mode, nonce reuse leaks XOR of plaintexts. Always use a unique nonce per encryption operation.

Pitfall 5: Ignoring Certificate Validation

Section titled “Pitfall 5: Ignoring Certificate Validation”

Disabling TLS certificate verification (verify=False in Python, InsecureRequestWarning Suppression) eliminates the entire trust model of TLS. This is common in development and Occasionally leaks into production. Never disable certificate validation.

MD5, SHA-1, DES, 3DES, RC4, and RSA with PKCS#1 v1.5 padding are all broken or deprecated. Use AES-256-GCM, ChaCha20-Poly1305, SHA-256/384, RSA-PSS, or Ed25519.

Without forward secrecy (ephemeral Diffie-Hellman), compromise of the server’s private key Compromises all past sessions. TLS 1.3 mandates forward secrecy, but TLS 1.2 with RSA key exchange Does not provide it. Ensure your cipher suites use ECDHE or DHE.

Reference Standards: NIST SP 800-57 (Key Management), NIST SP 800-63B (Digital Identity), NIST SP 800-38D (GCM), NIST SP 800-132 (PBKDF2), NIST FIPS 203/204/205 (Post-Quantum), RFC 8446 (TLS 1.3), RFC 8017 (RSA), RFC 8032 (EdDSA), RFC 7748 (Curve25519), RFC 5869 (HKDF).

This topic covers the mathematical techniques and concepts related to cryptography, including key theorems, methods, and problem-solving approaches.

Key concepts include:

  • fundamental definitions and theorems
  • algebraic and graphical methods
  • proof and logical reasoning
  • problem-solving strategies
  • applications and modelling

Regular practice with a variety of question types is essential to build fluency and confidence in applying these mathematical techniques.

Worked examples demonstrating the application of key concepts are covered in the detailed sub-pages linked above.