Skip to content

Compression, encryption, integrity

Practical 4.7 compression-encryption-integrity-annex.pdf · PDF

You send a folder of photos to a friend as a .zip. Someone says: "It's zipped, so it's safe." Is it? Smaller, yes. But can a stranger open it? And how would your friend know nobody changed a photo on the way?

Those are three different questions, and they need three different tools. In restic and the restore drill restic answered all three at once, without asking. Tramuntana Apps must send its weekly archive to the accountant: it should be small, nobody else may read it, and she must know it arrived unchanged. Today you do each job by hand.

What you will learn

  • Tell three jobs apart: compression (smaller), encryption (secret) and a checksum (unchanged)
  • Measure four compressors (gzip, zstd, xz, zip) on the same data and choose one for a case
  • Explain with your own numbers why text shrinks and random data does not
  • Encrypt and decrypt a file with a passphrase using age
  • Write a list of SHA-256 checksums and use it to catch a modified file
  • Why "it's zipped, so it's safe" forgets two of the three jobs

Three jobs, one parcel

Think of sending a parcel by post:

Job The parcel What it does to a file Tools on this page
Compression Vacuum-pack the jumper: same jumper, less space Writes the same information with fewer bytes by describing repetitions. Anyone can undo it gzip, zstd, xz, zip
Encryption A box with a padlock: only whoever has the key opens it Turns the bytes into noise that only the passphrase turns back age
Checksum The weight written on the label: if it changed on the way, somebody touched it Computes a short fingerprint of the file. One changed bit, another fingerprint. It cannot be undone sha256sum
flowchart LR
    F["<b>Archive</b><br>the jumper"] -->|"compress"| C["<b>Smaller</b><br>vacuum-packed"]
    C -->|"encrypt"| E["<b>Secret</b><br>box with a padlock"]
    E -->|"sha256sum"| S["<b>Fingerprint</b><br>the weight on the label"]
    S -->|"sent with the parcel"| R["<b>Accountant</b><br>checks the weight,<br>opens the padlock,<br>unpacks"]

Three things to keep straight:

  • Archive is not compress. tar only packs many files into one. The compressor makes that one file smaller. zip does both at once, file by file, and Windows opens it without installing anything.
  • Old and new. gzip is from 1992 (Jean-loup Gailly and Mark Adler) and is everywhere. zstd (Zstandard) is from 2016 (Yann Collet, at Facebook): the same job, much faster. You will measure it.
  • All of this is lossless: what comes out is identical, byte for byte, to what went in. JPEG and MP3 belong to another family, lossy compression: they throw information away for ever. Not today.

Build a sample and race four compressors

Install the tools and build a 50 MB sample with three kinds of content:

sudo apt install zstd zip unzip age
mkdir -p ~/lab37/sample
cd ~/lab37
seq 1 4000000 > sample/numbers.txt
cp -r /usr/share/common-licenses sample/licences
head -c 20M /dev/urandom > sample/random.bin
tar -cf sample.tar sample
ls -lh

seq writes the numbers from 1 to 4,000,000: 30 MB of text. The licences are a few ordinary texts. random.bin is 20 MB of random bytes. tar -cf packs the folder into one file without compressing: sample.tar is about 50M.

Now the race. time measures how long a command takes (read the real line); -k keeps the original file:

time gzip -k sample.tar
time zstd -k sample.tar
time xz -k sample.tar
time zip -q -r sample.zip sample
ls -l

Results from a test VM with 2 vCPU (your sizes will be almost the same; your times depend on your PC):

Tool File Size Time (real) Read it as
gzip sample.tar.gz 29.6 MB about 1.2 s the classic
zstd sample.tar.zst 22.3 MB about 0.15 s smaller and about ten times faster
xz sample.tar.xz 21.7 MB about 8.5 s the smallest, by a little, and very slow
zip sample.zip 29.6 MB about 1.2 s like gzip; opens everywhere

ls -l gives bytes: 29,589,180 bytes is 29.6 MB. Notice that nobody gets under 20 MB. Why?

Why random data does not shrink

Compress the two big files of the sample on their own:

gzip -k sample/numbers.txt sample/random.bin
ls -l sample
rm sample/*.gz
File Before (bytes) After gzip (bytes)
numbers.txt 30,888,896 8,496,758 (about a quarter)
random.bin 20,971,520 about 20,974,700: bigger

A compressor works by finding repetition and describing it more briefly: "the digits 1 to 9 again, with a new prefix". Numbers in order are full of patterns. Random bytes have no pattern to describe, so there is nothing to shorten, and the compressor's own bookkeeping makes the file slightly bigger.

Careful: compressing twice does not help

The first pass already removed the repetition. A .gz looks random to the next compressor, so running gzip on it again makes it grow. The same goes for photos and videos: they are already compressed.

Did compression lose anything? Unpack the .zst into another folder and compare:

mkdir out
tar -xf sample.tar.zst -C out
diff -r sample out/sample

diff prints nothing: every byte came back.

A secret: encryption with age

The office Wi-Fi password should not travel as plain text. age is a small, modern encryption tool. With -p it encrypts with a passphrase (a password, usually long). Type one and do not leave it empty: if you just press Enter, age invents a passphrase and prints it.

cp ~/tramuntana-share/admin/wifi.txt .
cat wifi.txt
age -p -o wifi.txt.age wifi.txt
file wifi.txt.age

file says age encrypted file. Now decrypt it (-d) and compare; then try once with a wrong passphrase:

age -d -o wifi-back.txt wifi.txt.age
diff wifi.txt wifi-back.txt
age -d wifi.txt.age

diff is silent: the decrypted file is identical. With the wrong passphrase you get age: error: incorrect passphrase, and nothing opens.

Careful: a zip password is not real encryption

The classic password of zip is weak: its own manual calls it "relatively weak standard encryption" and tells you to use a real encryption tool. Compress with one tool, encrypt with another.

Unchanged? Checksums with sha256sum

A checksum is a fingerprint of a file: a short string computed from every byte. Change one bit and you get a completely different fingerprint. SHA-256 is the algorithm; sha256sum is the command. You used it before to check a downloaded ISO.

Write the fingerprints of the two files you would send into a list, then check them (-c):

sha256sum sample.tar.zst wifi.txt.age > SHA256SUMS
cat SHA256SUMS
sha256sum -c SHA256SUMS

Each fingerprint is 64 hexadecimal characters (256 bits ÷ 4 bits per hex digit). The check answers sample.tar.zst: OK and wifi.txt.age: OK. Now somebody adds one byte on the way (>> adds to the end of a file):

echo x >> wifi.txt.age
sha256sum -c SHA256SUMS
sample.tar.zst: OK
wifi.txt.age: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

What a matching checksum does not tell you

A checksum is a fingerprint, not a lock: the file is still readable by anyone. And OK only means "identical to when the list was written". If an attacker wrote the list, OK proves nothing. That is why the accountant should get the fingerprints by another way (a message, a phone call).

Choosing

Case Choice Why
Every night, 100 GB of projects zstd Almost as small as xz, tens of times faster
A client on Windows who installs nothing zip Small for text, opens with nothing installed
Compress and encrypt Compress first, then encrypt Encrypted data looks random, and random data does not shrink

When you finish the practical, clean up: cd ~ and rm -r ~/lab37. Every step, with space for your numbers, is on the Practical 4.7 sheet.

Key takeaways

  • Three different jobs: compression makes it smaller, encryption makes it secret, a checksum proves it is unchanged.
  • tar only packs; gzip, zstd, xz and zip compress. zstd is the fast modern choice, zip the one Windows opens.
  • Compression is lossless here and works by describing repetition: text shrinks, random data (and anything already compressed or encrypted) does not.
  • age -p encrypts with a passphrase; a wrong passphrase opens nothing. A zip password is weak.
  • sha256sum -c checks a list of fingerprints: one changed byte gives FAILED.
  • Order matters: compress first, then encrypt.

Quick check

1. Why does a file of random bytes not get smaller with gzip?
  • It has no repetition to describe in a shorter way
  • It is too big for gzip to handle in one pass
  • It is already encrypted by the operating system
  • gzip only works with files that contain text

Compression shortens data by describing patterns and repetition. Random bytes have none, so the compressed file is as big as the original, or slightly bigger because of the compressor's bookkeeping.

2. Which tool makes a file unreadable without a passphrase?
  • age
  • zstd
  • sha256sum
  • tar

age does encryption. zstd compresses (anyone can decompress), sha256sum computes a fingerprint (the file stays readable) and tar only packs files together.

3. sha256sum -c SHA256SUMS answers report.pdf: FAILED. What do you know?
  • The file is not the same as when the list was written
  • The file has been encrypted with a passphrase
  • The file is too big to have a checksum
  • The file was compressed twice by mistake

A checksum changes completely when a single byte changes. FAILED means today's fingerprint does not match the one in the list: the file was modified or damaged since then.

4. Same 50 MB sample, four compressors. Which one gave almost the smallest file in a fraction of the time of the others?
  • zstd
  • gzip
  • xz
  • zip

zstd (2016) made a file only slightly bigger than xz (21.7 vs 22.3 MB) but in about 0.15 s, against 8.5 s for xz. gzip and zip were bigger and slower than zstd.

5. A client with Windows, who installs nothing, needs a folder of text logs in one small file. Which file do you send?
  • logs.zip
  • logs.tar.zst
  • logs.tar
  • logs.age

Windows opens a .zip with nothing installed, and text compresses well. A .tar is not compressed, .zst needs an extra program, and .age is encrypted, which nobody asked for.

6. You must compress and encrypt the weekly archive. In which order, and why?
  • Compress first, because encrypted data looks random and does not shrink
  • Encrypt first, because a compressor cannot read secret data safely
  • Either order, because both steps give exactly the same final size
  • Encrypt first, because compression would break the encryption

Encryption turns the bytes into noise, and noise has no repetition to compress. So you vacuum-pack the jumper first, then lock the box.

7. A colleague says: “The archive is zipped, so it is safe.” Select the two that are true.
  • Anyone who has the file can decompress it
  • Zipping alone does not prove the file arrived unchanged
  • Compression hides the content from anyone without a key
  • A zipped file can never be modified on the way

Compression only makes the file smaller: undoing it needs no secret. Secrecy needs encryption, and proof that nothing changed needs a checksum. Smaller, secret, unchanged: three different questions.

This week you typed the same backup commands again and again. Next you write them once, in a file, and the computer types them for you: Shell scripts.