| name | modern-crypto |
| description | Work with modern cryptographic primitives including AES, RSA, elliptic curves, and key derivation functions. Use this skill when implementing or breaking modern encryption schemes in CTF challenges. |
Modern Cryptography
Implement and analyze modern cryptographic algorithms.
AES Encryption/Decryption
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import base64
def aes_ecb_decrypt(ciphertext: bytes, key: bytes) -> bytes:
"""Decrypt AES-ECB."""
cipher = AES.new(key, AES.MODE_ECB)
plaintext = cipher.decrypt(ciphertext)
return unpad(plaintext, AES.block_size)
def aes_cbc_decrypt(ciphertext: bytes, key: bytes, iv: bytes) -> bytes:
"""Decrypt AES-CBC."""
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
return unpad(plaintext, AES.block_size)
def aes_ctr_decrypt(ciphertext: bytes, key: bytes, nonce: bytes) -> bytes:
"""Decrypt AES-CTR."""
cipher = AES.new(key, AES.MODE_CTR, nonce=nonce)
return cipher.decrypt(ciphertext)
# Example
key = b'Sixteen byte key'
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(b'Secret message!', AES.block_size))
plaintext = aes_cbc_decrypt(ciphertext, key, iv)
print(plaintext.decode())
XOR Operations
def xor_bytes(a: bytes, b: bytes) -> bytes:
"""XOR two byte sequences (cycles shorter one)."""
result = []
for i in range(max(len(a), len(b))):
result.append(a[i % len(a)] ^ b[i % len(b)])
return bytes(result)
def find_xor_key(ciphertext: bytes, known_plaintext: bytes) -> bytes:
"""Recover XOR key from known plaintext attack."""
return xor_bytes(ciphertext[:len(known_plaintext)], known_plaintext)
# Example
plaintext = b"CTF{secret_flag}"
key = b"KEY"
ciphertext = xor_bytes(plaintext, key)
recovered_key = find_xor_key(ciphertext, b"CTF{")
print(f"Key: {recovered_key}")
RSA Basics
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
def rsa_decrypt_private(ciphertext: bytes, private_key: RSA.RsaKey) -> bytes:
"""Decrypt with RSA private key."""
cipher = PKCS1_OAEP.new(private_key)
return cipher.decrypt(ciphertext)
def rsa_raw_decrypt(c: int, d: int, n: int) -> int:
"""Raw RSA decryption: m = c^d mod n."""
return pow(c, d, n)
def int_to_bytes(n: int) -> bytes:
"""Convert integer to bytes."""
return n.to_bytes((n.bit_length() + 7) // 8, 'big')
def bytes_to_int(b: bytes) -> int:
"""Convert bytes to integer."""
return int.from_bytes(b, 'big')
# Example: Raw RSA
n = 77 # Small example
e = 7
d = 43 # Private exponent
c = 48 # Ciphertext
m = rsa_raw_decrypt(c, d, n)
print(f"Plaintext: {m}")
Diffie-Hellman
from Crypto.Random import random
def dh_key_exchange(p: int, g: int, private_key: int) -> tuple:
"""Diffie-Hellman key exchange."""
public_key = pow(g, private_key, p)
return public_key
def dh_shared_secret(other_public: int, my_private: int, p: int) -> int:
"""Compute DH shared secret."""
return pow(other_public, my_private, p)
# Example
p = 23 # Prime modulus
g = 5 # Generator
# Alice
a = random.randint(2, p-2)
A = dh_key_exchange(p, g, a)
# Bob
b = random.randint(2, p-2)
B = dh_key_exchange(p, g, b)
# Shared secret
secret_alice = dh_shared_secret(B, a, p)
secret_bob = dh_shared_secret(A, b, p)
assert secret_alice == secret_bob
Elliptic Curve Cryptography
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
def generate_ec_keypair():
"""Generate ECDSA keypair."""
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()
return private_key, public_key
def ec_point_add(p: int, a: int, P: tuple, Q: tuple) -> tuple:
"""Add two points on elliptic curve y^2 = x^3 + ax + b mod p."""
if P is None:
return Q
if Q is None:
return P
x1, y1 = P
x2, y2 = Q
if x1 == x2 and y1 != y2:
return None # Point at infinity
if P == Q:
# Point doubling
lam = (3 * x1**2 + a) * pow(2 * y1, -1, p) % p
else:
# Point addition
lam = (y2 - y1) * pow(x2 - x1, -1, p) % p
x3 = (lam**2 - x1 - x2) % p
y3 = (lam * (x1 - x3) - y1) % p
return (x3, y3)
def ec_scalar_mult(p: int, a: int, k: int, P: tuple) -> tuple:
"""Scalar multiplication on elliptic curve."""
result = None
temp = P
while k > 0:
if k & 1:
result = ec_point_add(p, a, result, temp)
temp = ec_point_add(p, a, temp, temp)
k >>= 1
return result
Key Derivation Functions
from Crypto.Protocol.KDF import PBKDF2, scrypt
from Crypto.Hash import SHA256, SHA512
import hashlib
def derive_key_pbkdf2(password: str, salt: bytes, key_len: int = 32) -> bytes:
"""Derive key using PBKDF2."""
return PBKDF2(password, salt, dkLen=key_len, count=100000, hmac_hash_module=SHA256)
def derive_key_scrypt(password: str, salt: bytes, key_len: int = 32) -> bytes:
"""Derive key using scrypt."""
return scrypt(password, salt, key_len=key_len, N=2**14, r=8, p=1)
# Example
password = "my_secure_password"
salt = get_random_bytes(16)
derived_key = derive_key_pbkdf2(password, salt)
print(f"Derived key: {derived_key.hex()}")
Block Cipher Modes Analysis
def detect_ecb(ciphertext: bytes, block_size: int = 16) -> bool:
"""Detect ECB mode by looking for repeated blocks."""
blocks = [ciphertext[i:i+block_size] for i in range(0, len(ciphertext), block_size)]
return len(blocks) != len(set(blocks))
def analyze_iv_reuse(ct1: bytes, ct2: bytes, block_size: int = 16) -> bool:
"""Detect CBC IV reuse (first blocks will be same for same plaintext start)."""
return ct1[:block_size] == ct2[:block_size]
# ECB penguin test
ciphertext = bytes.fromhex("aabbccdd" * 4 + "11223344" * 4 + "aabbccdd" * 4)
if detect_ecb(ciphertext):
print("ECB mode detected - repeated blocks found")