Asymmetric encryption’s magic trick is that you can give one key away to everyone, and the other key you keep secret, and still securely communicate with anyone who has your public key.
Let’s see it in action. Imagine Alice wants to send a secret message to Bob. Bob generates a pair of keys: a public key (which he shares freely) and a private key (which he keeps hidden).
import cryptography
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
# Bob generates his keys
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
public_key = private_key.public_key()
# Bob serializes his public key to share
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
# Alice wants to send a message
message = b"This is a top secret message!"
# Alice encrypts the message using Bob's public key
encrypted_message = public_key.encrypt(
message,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# Alice sends the encrypted message to Bob
# Bob receives the encrypted message and decrypts it using his private key
original_message = private_key.decrypt(
encrypted_message,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print(f"Original message: {original_message.decode()}")
The core problem asymmetric encryption solves is secure key exchange. In the old days (symmetric encryption), if Alice and Bob wanted to chat secretly, they’d need to agree on a shared secret key beforehand. How do they do that without an eavesdropper listening in on their initial key exchange? Asymmetric encryption sidesteps this entirely. Bob can blast his public key out on a billboard, and Alice can use it to encrypt messages that only Bob can decrypt with his corresponding private key.
Internally, it relies on mathematical problems that are easy to compute in one direction but incredibly hard to reverse. For RSA, the most common algorithm, this is the difficulty of factoring large prime numbers. When Bob generates his keys, he’s essentially picking two massive prime numbers, multiplying them to get a large composite number (part of his public key), and then using these primes in complex calculations to derive his private key. Anyone with the public key can perform the encryption calculation, but without knowing the original prime factors, it’s computationally infeasible to reverse-engineer the private key from the public key and the encrypted message.
The public key is used for encryption, and the private key is used for decryption. This is the fundamental "asymmetry." You can think of the public key as a mailbox slot – anyone can drop a letter in, but only the person with the mailbox key (the private key) can open it and read the letters. This mechanism is the bedrock of secure communication on the internet, powering everything from HTTPS (secure websites) to secure email (PGP/GPG) and digital signatures.
A common misconception is that asymmetric encryption is used for encrypting large amounts of data directly. While technically possible, it’s computationally far too expensive for that. Instead, it’s typically used to encrypt a symmetric session key. A much faster symmetric encryption algorithm then uses this session key to encrypt the actual bulk data of the communication. This hybrid approach gives you the secure key exchange benefits of asymmetric encryption and the speed of symmetric encryption.
The next concept you’ll grapple with is how to ensure the public key you’re using actually belongs to the person you think it does.