RSA Padding Schemes (PKCS-1 v1.5 vs OAEP vs Unpadded)
- •
What it is
- •
Textbook RSA () applied directly to a raw message is deterministic and structured — the same message always encrypts to the same ciphertext, and messages that are small, related, or predictable in format leak exploitable structure (as the sheer number of "unpadded RSA" attacks in this graph demonstrates: small-exponent cube-root attacks, Hastad's broadcast, Franklin-Reiter, Coppersmith's stereotyped-message recovery). Real-world RSA never encrypts raw messages — it always applies a padding scheme first, specifically to break exactly this kind of structure. Two standards matter most: PKCS#1 v1.5 — the older scheme, prepending
0x00 0x01followed by non-zero random padding bytes, a0x00separator, then the message — is simple but has had multiple practical attacks over the decades (Bleichenbacher's padding-oracle attack among them), since it's not provably secure and has no built-in randomization guarantee strong enough for modern standards. OAEP (Optimal Asymmetric Encryption Padding) — used for encryption in modern deployments — mixes the message with random bytes through two rounds of a Feistel-like construction built from a hash function, giving provable security guarantees (semantic security, resistance to chosen-ciphertext attacks) that raw PKCS#1 v1.5 encryption lacks. A related, separate PKCS#1-v1.5-based construction (EMSA-PKCS1-v1.5) is used for signing rather than encryption — structurally similar but serving a different purpose, and vulnerable to its own class of attacks (like Bleichenbacher's low-exponent signature forgery) if implemented carelessly.
- •
- •
When to apply
- •
Any time you see raw
pow(m, e, N)with no padding step, or a challenge naming "PKCS1", "OAEP", or "EMSA" — knowing which scheme (or the absence of one) is in play tells you which whole family of attacks in this graph might be relevant.\
- •
- •
Math
- •
No single formula — padding's entire purpose is structural/informational: transform a possibly-small, possibly-predictable, possibly-repeated message into one that's large, randomized, and unique on every encryption, defeating the algebraic structure that unpadded-RSA attacks rely on.
- •
- •
Worked example
- •
Encrypting the same message twice under real OAEP padding produces two completely different ciphertexts (thanks to fresh randomness each time) — contrast this with unpadded textbook RSA, where the same message always produces the identical ciphertext, immediately leaking that two ciphertexts share a plaintext (exactly what several attacks in this graph exploit).
- •
- •
Python
- •
from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA cipher = PKCS1_OAEP.new(RSA.import_key(pubkey_pem)) ciphertext = cipher.encrypt(plaintext_bytes) # randomized, structurally safe against the unpadded-RSA attack family
- •
- •
- •
Cards
- •
Why does encrypting the same message twice under OAEP produce different ciphertexts, while unpadded RSA doesn't?
- •
OAEP mixes in fresh randomness on every encryption; unpadded textbook RSA is a deterministic function of the message alone.
- •
- •
What's the practical difference in purpose between PKCS#1 v1.5/OAEP (encryption) and EMSA-PKCS1-v1.5 (signing)?
- •
Encryption padding hides and randomizes a message before encrypting it; signing padding structures a hash digest before it gets "encrypted" with a private key to produce a signature — related constructions, different goals.
- •
- •