Mật mã học với Python: AES, RSA và tự build một hệ thống mã hóa an toàn

Hiểu mật mã học không chỉ để tấn công (crack weak crypto), mà còn để xây dựng hệ thống an toàn. Bài này đi qua AES, RSA và hybrid encryption bằng Python.

AES — Symmetric Encryption

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

def encrypt(key: bytes, plaintext: str) -> tuple[bytes, bytes]:
    """AES-256-GCM — authenticated encryption"""
    aesgcm = AESGCM(key)
    nonce = os.urandom(12)  # 96-bit nonce cho GCM
    ciphertext = aesgcm.encrypt(nonce, plaintext.encode(), None)
    return nonce, ciphertext

def decrypt(key: bytes, nonce: bytes, ciphertext: bytes) -> str:
    """Decrypt và verify authenticity"""
    aesgcm = AESGCM(key)
    plaintext = aesgcm.decrypt(nonce, ciphertext, None)
    return plaintext.decode()

# Demo
key = AESGCM.generate_key(bit_length=256)
nonce, ct = encrypt(key, "Hello danh.me/!")
print(f"Encrypted: {ct.hex()}")
print(f"Decrypted: {decrypt(key, nonce, ct)}")

RSA — Asymmetric Encryption

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes, serialization

# Generate key pair
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)
public_key = private_key.public_key()

# Encrypt với public key
ciphertext = public_key.encrypt(
    b"Secret message",
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

# Decrypt với private key
plaintext = private_key.decrypt(
    ciphertext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print(plaintext)  # b"Secret message"

Hybrid Encryption (RSA + AES)

def hybrid_encrypt(public_key, message: str) -> dict:
    """Mã hóa hybrid: AES key được mã hóa bởi RSA"""
    # Generate random AES key
    aes_key = AESGCM.generate_key(bit_length=256)

    # Encrypt message với AES
    nonce, ciphertext = encrypt(aes_key, message)

    # Encrypt AES key với RSA public key
    encrypted_key = public_key.encrypt(
        aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    return {
        "encrypted_key": encrypted_key.hex(),
        "nonce": nonce.hex(),
        "ciphertext": ciphertext.hex()
    }

def hybrid_decrypt(private_key, package: dict) -> str:
    """Giải mã hybrid"""
    # Decrypt AES key với RSA private key
    aes_key = private_key.decrypt(
        bytes.fromhex(package["encrypted_key"]),
        padding.OAEP(...)
    )

    # Decrypt message với AES key
    return decrypt(
        aes_key,
        bytes.fromhex(package["nonce"]),
        bytes.fromhex(package["ciphertext"])
    )

Tấn công Weak Crypto

# ECB mode — pattern leak
from Crypto.Cipher import AES

# ECB encrypt cùng plaintext block → cùng ciphertext block
cipher = AES.new(key, AES.MODE_ECB)
# Block 1: "ATTACKATDAWN!!!!" → ct1
# Block 2: "ATTACKATDAWN!!!!" → ct1  ← SAME!
# → Attacker có thể detect patterns trong ciphertext

# CBC với predictable IV → BEAST attack
# Padding oracle → decrypt từng byte

# RSA với small exponent (e=3) → Cube root attack
import gmpy2
c = ciphertext_as_int
m, exact = gmpy2.iroot(c, 3)
if exact:
    print("RSA small exponent attack success:", m)

Leave a Comment