No. 04 — Lab 02

Bob to Amaka

sealed

Bob encrypts the 300-word message from Lab 01 so only Amaka can read it. Then one bit is flipped on the way. Every command below was run for real, and the output is exactly what OpenSSL printed.

3072RSA key bits
256AES key bits
1Bit flipped in transit
17Bytes damaged after decryption

01 — Setup

Two key pairs

Amaka and Bob each make an RSA key pair and swap public keys. A private key never leaves its owner. These are demo keys made for this page and not published.

Amaka
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out amaka_private.pem
Amaka
openssl pkey -in amaka_private.pem -pubout -out amaka_public.pem
Bob
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out bob_private.pem
Bob
openssl pkey -in bob_private.pem -pubout -out bob_public.pem

02 — Bob sends

Encrypt and sign

RSA is too slow and too small for 300 words, so Bob uses the standard hybrid pattern. A random AES-256 session key encrypts the message, and Amaka's public key encrypts the session key. He also signs the message with his private key.

Bob
openssl rand -hex -out session.key 32
Bob
openssl enc -aes-256-cbc -pbkdf2 -salt -in bob-original.txt -out message.enc -pass file:session.key
Bob
openssl pkeyutl -encrypt -pubin -inkey amaka_public.pem -pkeyopt rsa_padding_mode:oaep -in session.key -out session.key.enc
Bob
openssl dgst -sha256 -sign bob_private.pem -out message.sig bob-original.txt
Bob
wc -c bob-original.txt message.enc session.key.enc message.sig
1639 bob-original.txt
1664 message.enc
 384 session.key.enc
 384 message.sig
4071 total
Bob
od -An -tx1 -N32 message.enc
 53 61 6c 74 65 64 5f 5f be 55 b8 0b c9 2b e2 74
 e7 47 d8 dd ec fb 6f 39 3a 62 75 18 2c b8 8c 06

03 — Amaka receives

Decrypt and verify

Amaka unlocks the session key with her private key, decrypts the message, checks Bob's signature, and compares hashes with the original.

Amaka
openssl pkeyutl -decrypt -inkey amaka_private.pem -pkeyopt rsa_padding_mode:oaep -in session.key.enc -out session.key.recovered
Amaka
openssl enc -d -aes-256-cbc -pbkdf2 -in message.enc -out message.recovered.txt -pass file:session.key.recovered
Amaka
openssl dgst -sha256 -verify bob_public.pem -signature message.sig message.recovered.txt
Verified OK
Amaka
sha256sum bob-original.txt message.recovered.txt
ebd64f158907aaf282b37b1d615f438049f0453828662ab1b48f52e8b70e2d70  bob-original.txt
ebd64f158907aaf282b37b1d615f438049f0453828662ab1b48f52e8b70e2d70  message.recovered.txt

04 — Disruption

One bit flipped in transit

Now damage the encrypted message on its way: flip a single bit. Amaka decrypts it exactly as before.

In transit
python -c "d=bytearray(open('message.enc','rb').read()); d[100]^=1; open('message.damaged.enc','wb').write(d)"
Amaka
openssl enc -d -aes-256-cbc -pbkdf2 -in message.damaged.enc -out message.damaged.txt -pass file:session.key.recovered
Amaka
sha256sum message.enc message.damaged.enc
8f8f820d915a0a4cb0bbd6907159db46fa8882e4a28ab6f288a6bd742609e3aa  message.enc
d13c0880373063855319a572b51666b405dfa55c901c63dfb48062352c442dc4  message.damaged.enc
Amaka
sha256sum bob-original.txt message.damaged.txt
ebd64f158907aaf282b37b1d615f438049f0453828662ab1b48f52e8b70e2d70  bob-original.txt
6804290c11beb6dd20c6a494f78c5d478aaca6ee1d89e9ae344031074c28d72b  message.damaged.txt
Amaka
cmp -l bob-original.txt message.damaged.txt | wc -l
17
Amaka
openssl dgst -sha256 -verify bob_public.pem -signature message.sig message.damaged.txt
Verification failure

05 — Result

Encryption is not integrity

Confidentiality worked. The ciphertext starts with the bytes 53 61 6c 74 65 64 5f 5f, which spell "Salted__", followed by random-looking data. Without Amaka's private key nobody can recover the session key.

Integrity failed silently. After one flipped bit, decryption finished with no error, but 17 bytes were wrong and the SHA-256 hash had nothing in common with the original, the same avalanche effect as Lab 01. AES-CBC garbles the block that was hit and flips one bit in the next, and it never complains.

The signature caught it. Bob's signature verified on the good copy and failed on the damaged one. That is why real systems use authenticated encryption such as AES-GCM or ChaCha20-Poly1305, or sign what they send.

06 — Run it yourself

Same commands, your machine

Run the commands in order in Git Bash, WSL or Linux (Git for Windows includes OpenSSL). Use python3 instead of python on Linux and macOS. Start from bob-original.txt.

Never publish a key. Anything ending in _private.pem or session.key must stay off GitHub. Add *.pem and session.key* to your .gitignore.


←integrityPrevious→forensicsNext

All labs