In today’s digital world, where secure communication, authentication, and data integrity are non-negotiable, private-public key encryption (also called asymmetric cryptography) plays a foundational role. From HTTPS in your browser to SSH logins, cryptocurrency wallets, and email encryption, this elegant cryptographic system enables trust without prior shared secrets.
In this blog, we’ll dive into:
- The core concepts behind asymmetric encryption
- How it differs from symmetric encryption
- The mathematics (intuitively explained) behind popular algorithms like RSA and ECC
- Real-world examples and code snippets
- Common use cases and pitfalls
Whether you’re a curious beginner or a seasoned developer brushing up on fundamentals, you’ll find something valuable here.
A Quick Comparison of Symmetric vs. Asymmetric Encryption
Before we dive into public-key crypto, let’s contrast it with its older sibling: symmetric encryption.
| Feature | Symmetric Encryption | Asymmetric Encryption |
|---|---|---|
| Keys | One shared secret key | Two keys: public + private |
| Speed | Fast | Slower (computationally heavy) |
| Key Distribution | Hard (needs secure channel) | Easy (public key can be shared) |
| Use Cases | Bulk data encryption (e.g., AES) | Key exchange, digital signatures |
Symmetric encryption (like AES) is great for encrypting large amounts of data quickly, but you need a way to securely share the secret key beforehand. That’s where asymmetric encryption shines: it solves the key distribution problem.
Two Keys, One Mathematical Bond
In asymmetric cryptography:
- The public key is shared openly.
- The private key is kept secret.
- Data encrypted with one key can only be decrypted with the other.
This creates two powerful capabilities:
- Confidentiality: Encrypt with someone’s public key → only they can decrypt with their private key.
- Authentication & Integrity: Sign data with your private key → anyone can verify it using your public key.
Crucial Insight: The public key cannot be used to derive the private key, even though they’re mathematically linked. This is the “hard problem” that makes the system secure.
How It Works
Example 1: Sending a Secure Message
Alice wants to send a confidential message to Bob.
- Bob generates a key pair:
- Public key:
Bob_pub - Private key:
Bob_priv(kept secret)
- Public key:
- Bob shares
Bob_pubwith Alice (e.g., via email, website, key server). - Alice encrypts her message using
Bob_pub. - Bob receives the ciphertext and decrypts it with
Bob_priv.
Even if Eve intercepts the message and has Bob_pub, she cannot decrypt it, because the private key is required.
Example 2: Digital Signatures
Now, Alice wants to prove a message truly came from her.
- Alice hashes her message →
H = SHA256("Hello Bob!") - She encrypts the hash with her private key:
Sig = Encrypt(H, Alice_priv) - She sends both the message and
Sigto Bob. - Bob:
- Hashes the received message →
H' - Decrypts
SigusingAlice_pub→ getsH - Checks if
H == H'
- Hashes the received message →
If they match, the message is authentic and unchanged.
Note: In practice, we don’t encrypt the whole message, just its hash (for efficiency and security).
Under the Hood: RSA and ECC
Two major algorithms power most public-key cryptography today:
1. RSA (Rivest–Shamir–Adleman)
Based on: The difficulty of factoring large prime numbers.
Key Generation (Simplified):
- Choose two large primes:
pandq - Compute
n = p * q - Compute Euler’s totient:
φ(n) = (p-1)(q-1) - Choose public exponent
e(commonly 65537) such that1 < e < φ(n)andgcd(e, φ(n)) = 1 - Compute private exponent
dsuch that(d * e) mod φ(n) = 1
- Public key:
(n, e) - Private key:
(n, d)
Encryption:
ciphertext = plaintext^e mod n
Decryption:
plaintext = ciphertext^d mod n
RSA requires large keys (2048+ bits) for security today.
Python Example (using cryptography library):
1from cryptography.hazmat.primitives.asymmetric import rsa, padding
2from cryptography.hazmat.primitives import hashes
3from cryptography.hazmat.primitives import serialization
4
5
6# Generate keys
7private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
8public_key = private_key.public_key()
9
10# We are writing the keys to files for demonstration purposes
11with open("public_key.pem", "wb") as f:
12 f.write(public_key.public_bytes(
13 encoding=serialization.Encoding.PEM,
14 format=serialization.PublicFormat.SubjectPublicKeyInfo
15 ))
16
17with open("private_key.pem", "wb") as f:
18 f.write(private_key.private_bytes(
19 encoding=serialization.Encoding.PEM,
20 format=serialization.PrivateFormat.PKCS8,
21 encryption_algorithm=serialization.NoEncryption()
22 ))
23
24# Encrypt
25message = b"Secret message"
26ciphertext = public_key.encrypt(
27 message,
28 padding.OAEP(
29 mgf=padding.MGF1(algorithm=hashes.SHA256()),
30 algorithm=hashes.SHA256(),
31 label=None
32 )
33)
34
35# Decrypt
36plaintext = private_key.decrypt(
37 ciphertext,
38 padding.OAEP(
39 mgf=padding.MGF1(algorithm=hashes.SHA256()),
40 algorithm=hashes.SHA256(),
41 label=None
42 )
43)
44
45print(plaintext) # b"Secret message"2. ECC (Elliptic Curve Cryptography)
Based on: The algebraic structure of elliptic curves over finite fields. A type of math involving curved lines and numbers that reset after a certain point, designed so that going forward is easy, but going backward without a secret key is practically impossible.
- Offers same security as RSA with much smaller keys (e.g., 256-bit ECC ≈ 3072-bit RSA).
- Faster and more efficient, ideal for mobile and embedded systems.
Common curves: secp256k1 (used in Bitcoin), Curve25519 (used in Signal, SSH).
ECC Key Generation (Conceptual):
- Choose a standard elliptic curve (e.g.,
secp256r1) - Pick a random private key
d(a large integer) - Compute public key
Q = d * G, whereGis a known base point on the curve
The security relies on the Elliptic Curve Discrete Logarithm Problem (ECDLP): given Q and G, it’s computationally infeasible to find d.
ECC is now the preferred choice for new systems (TLS 1.3, blockchain, etc.).
Real-World Use Cases
1. TLS/SSL (HTTPS)
- Your browser uses the server’s public key to establish a secure session.
- Asymmetric crypto exchanges a symmetric key (e.g., AES) for efficient data transfer.
2. SSH Authentication
- Your SSH client proves identity using a private key; the server verifies with your public key.
3. PGP/GPG Email Encryption
- Encrypt emails with recipient’s public key; sign with your private key.
4. Cryptocurrencies
- Bitcoin wallet addresses are derived from public keys.
- Transactions are signed with private keys to prove ownership.
Common Pitfalls & Best Practices
| Mistake | Why It’s Bad | Best Practice |
|---|---|---|
| Reusing RSA keys for encryption + signing | Increases attack surface | Use separate keys or follow PKCS standards |
| Using small key sizes (e.g., 1024-bit RSA) | Vulnerable to factorization | Use ≥2048-bit RSA or 256-bit ECC |
| Not using padding (e.g., textbook RSA) | Vulnerable to chosen-ciphertext attacks | Always use OAEP (encryption) or PSS (signing) |
| Hardcoding private keys in code | Massive security risk | Store in secure vaults (e.g., HashiCorp Vault, AWS KMS) |
Private-public key encryption is not just a cryptographic curiosity, it’s the trust engine of the internet. By elegantly solving the key distribution problem, it enables secure communication between strangers across an insecure network.
While the math behind RSA and ECC can seem daunting, modern libraries abstract away the complexity. As a developer, your job isn’t to implement these algorithms from scratch, but to use them correctly, respect key hygiene, and understand their limits.
As you explore steganography or other low-level projects (like embedding data in media), remember: encryption protects content, steganography hides its existence, and the two can even work together!
Further Reading
- PKCS Standards
- NIST Guidelines on Key Management
- Serious Cryptography by Jean-Philippe Aumasson
- Cloudflare’s ECC explanation
Got questions or want a deep dive into a specific algorithm? Leave a comment below!
Happy encrypting!