A stream cipher (or one-time pad) encrypts by XOR: $C = M \oplus K$. Why does this give confidentiality but no integrity, and what can an attacker do because of it?
Because XOR is transparent to tampering: flipping a bit of the ciphertext flips exactly the same bit of the decrypted plaintext, so an attacker can make controlled changes that still decrypt cleanly — the receiver has no way to notice.
* XOR malleability: flipping a ciphertext bit flips exactly that plaintext bit on decryption — undetected, which is why a MAC is needed. *
The malleability problem:
- Decryption is $M = C \oplus K$. If the attacker flips ciphertext bit $i$ (sends $C \oplus e_i$), the receiver computes $(C \oplus e_i) \oplus K = M \oplus e_i$ — plaintext bit $i$ flips, everything else stays intact.
- The attacker never touches the key. If they know or guess part of the plaintext — say a field that reads
PAY 0100— they can XOR in the difference to flip it toPAY 9900, and it decrypts to the tampered value with no error raised.
Confidentiality and integrity are different goals:
- Confidentiality (secrecy) — a good keystream hides the plaintext; a true one-time pad does this perfectly.
- Integrity (tamper-evidence) — detecting that a message was altered. XOR encryption provides none of this, no matter how strong the keystream. Perfect secrecy says nothing about tamper-detection.
The fix: add a separate integrity mechanism — a MAC (message authentication code) or an authenticated-encryption mode (e.g. AES-GCM) — so any bit-flip is caught. Encrypting a message does not authenticate it.
Tip: "Encryption ≠ authentication." This is exactly why real protocols pair a cipher with a MAC (encrypt-then-MAC) instead of trusting the cipher alone.
Go deeper:
Malleability (Wikipedia) — the formal bit-flipping property of XOR ciphers.
Stream cipher (Wikipedia) — how keystream XOR works.
Message authentication code (Wikipedia) — the MAC that restores tamper-detection.