Day 2 of 5
⏱ ~60 minutes
Cryptography in 5 Days — Day 2

Asymmetric Encryption & PKI

Asymmetric cryptography solves the key distribution problem: two parties who have never met can establish a secure channel. Today covers RSA, elliptic curve cryptography, digital signatures, and the certificate infrastructure that secures the web.

RSA: How It Works

RSA security relies on the practical difficulty of factoring large numbers. Key generation: choose two large primes p and q, compute n = p*q, find e and d such that e*d ≡ 1 (mod φ(n)). Public key is (e, n), private key is (d, n). Encryption: c = m^e mod n. Decryption: m = c^d mod n. RSA-2048 requires factoring a 617-digit number — currently infeasible. RSA-4096 is preferred for new deployments.

Elliptic Curve Cryptography (ECC)

ECC provides equivalent security to RSA with much smaller keys: 256-bit ECC ≈ 3072-bit RSA security. This means faster operations and smaller TLS handshakes. ECDSA signs data; ECDH exchanges keys. Curve25519 (designed by Daniel Bernstein) is the modern recommendation — it avoids the potential backdoored NIST curves and is extremely fast. Ed25519 signatures are used in SSH, TLS 1.3, and Signal.

PKI and X.509 Certificates

Public Key Infrastructure (PKI) solves the problem of trusting public keys. A Certificate Authority (CA) signs a certificate binding a public key to an identity (domain name, organization). Your browser trusts 130+ root CAs. When you visit https://precisionaiacademy.com, TLS validates that the certificate was signed by a trusted CA and matches the domain name.

python
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
    Ed25519PrivateKey
)
from cryptography.hazmat.primitives.serialization import (
    Encoding, PublicFormat, PrivateFormat, NoEncryption
)

# Generate Ed25519 key pair (modern, fast, secure)
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

# Sign a message
message = b'Precision AI Academy contract - April 2026'
signature = private_key.sign(message)
print(f'Signature: {signature.hex()[:32]}...')

# Verify signature
try:
    public_key.verify(signature, message)
    print('Signature VALID')
except Exception:
    print('Signature INVALID')

# Serialize public key (for sharing)
pub_bytes = public_key.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
print(pub_bytes.decode())
💡
For new systems, prefer Ed25519 over RSA or ECDSA. It is faster, simpler to implement correctly, has no small-subgroup attacks, and produces compact 64-byte signatures.
📝 Day 2 Exercise
Generate Keys and Sign Data
  1. Generate an Ed25519 key pair and save both keys to PEM files
  2. Sign a text file containing your name and today's date
  3. Verify the signature successfully
  4. Modify one byte in the signed file and verify the signature fails
  5. Generate a self-signed X.509 certificate using OpenSSL for practice: openssl req -x509 -newkey ed25519 -nodes -out cert.pem -days 365

Day 2 Summary

  • RSA security relies on integer factorization being computationally hard
  • ECC provides RSA-equivalent security with 10x smaller keys
  • Ed25519 is the modern standard for digital signatures
  • PKI binds public keys to identities through CA-signed X.509 certificates
  • Certificate chains allow any client to verify server identity without pre-sharing keys
Challenge

Build a simple secure message system: Party A generates an Ed25519 key pair and shares the public key. Party B signs a message and sends it with the signature. Party A verifies it. Extend to add AES-256-GCM encryption of the message content.

Finished this lesson?