Skip to main content
See Security Labs

SEC401 - Data Security Technologies

Lab 4.1 - Hashing and Cryptographic Validation

Solo, Lab

Focus: Cryptography

Level: SEC401

Date: Apr 2026

Artifacts: Sanitized terminal screenshots of sha256sum, GPG key generation, detached signatures, signature verification (good and bad), and exiftool metadata review

TL;DR

  • Proved SHA-256 is content-based by renaming a file (hash unchanged) vs. editing one byte (hash diverged)
  • Generated an RSA 3072-bit GPG key, signed a file, imported a third-party public key
  • Caught a tampered Bankruptcy.docx via a BAD signature, then verified a clean backup

Skills demonstrated

SHA-256 file integrity validationGPG key generation and keyring managementDetached signature creation and verificationPublic key import and trust model reviewExif/document metadata triageIncident workflow: restoring from a signed backup after tamper detection

Note: Course-provided PCAPs and lab instructions are not shared. Only my own captures and sanitized notes are published.

Why this matters

Hashing and signing are how defenders catch silent tampering — the attacker who changes one byte of a document, contract, or binary. Without integrity checks, you have no way to tell whether a file is the one the author sent or something an intermediate actor modified. This lab is the blue-team equivalent of 'don't trust the file, verify the signature.'

Context

This lab walks through the core building blocks of cryptographic integrity — hashing, key pairs, and digital signatures — using sha256sum and GnuPG. It ends with a realistic scenario: a suspected-tampered document that fails signature verification, forcing a restore from a backup whose signature is valid.

Tools used

sha256sumxxdsedgpg (GnuPG 2.2.27)exiftool

Steps taken

1Hash is content-based, not name-based

Created test-file.txt containing 'Hello'. Computed its SHA-256 (66a0...bb35f18), inspected the bytes with xxd (48 65 6c 6c 6f 0a = Hello\n), then renamed the file to renamed-file.txt. Re-hashed: the digest was identical. Hashes are computed over file contents, not metadata.

$ echo "Hello" > test-file.txt && sha256sum test-file.txt && xxd test-file.txt && mv test-file.txt renamed-file.txt && sha256sum renamed-file.txt
echo "Hello" > filewrite 6 bytes (Hello\n) to a file
sha256sumcompute SHA-256 digest
xxdhex + ASCII dump
mvrename without changing contents

2One-byte change, completely different hash

Used sed to change every H to h in place (a single-byte change: 0x48 → 0x68). Re-hashed: the digest went from 66a0...bb35f18 to 5891...6be03, no resemblance to the original. This is the avalanche property of SHA-256: small input changes produce massive output changes.

$ sed -i 's/H/h/g' renamed-file.txt && sha256sum renamed-file.txt
sed -iedit file in place
's/H/h/g'substitute H with h, globally

3Generate an RSA 3072 GPG key

Ran the interactive key generation wizard. Chose RSA and RSA (1), 3072-bit keysize, no expiration, identity sec401 <sec401@sans.org>. GPG generated primary signing/certification (SC) key and an encryption (E) subkey. Entropy-gathering prompt appeared twice because two primes needed to be generated.

$ gpg --full-generate-key
--full-generate-keyfull interactive key generation (vs. quick-generate)

4Inspect the keyring

Listed public and secret keys. pub rsa3072 2026-04-13 [SC] with fingerprint A2B39B421129567517A5ECEA9B00C9116C092134, trust [ultimate] because it's our own key, plus a matching [E] encryption subkey. The secret-keys listing shows the same fingerprint under 'sec' confirming we hold the private half.

$ gpg --list-keys && gpg --list-secret-keys

5Sign a file with a detached ASCII-armored signature

Produced an external .asc signature for renamed-file.txt. Detached sigs are the pattern used for release artifacts: ship the file and the .asc alongside each other. Verified locally and GPG reported 'Good signature from sec401' with the full fingerprint.

$ gpg --sign --armor --output renamed-file.txt.asc --detach-sig renamed-file.txt && gpg --verify renamed-file.txt.asc
--signsign
--armorASCII-armored output (.asc, not binary .sig)
--detach-sigsignature in a separate file

6Import a third-party public key

Imported Madison Jeffries's public key from the lab backup directory. Post-import, --list-keys shows two pubkeys: our own at [ultimate] trust and Jeffries's (D200...BD90, rsa4096) at [unknown] trust, which is the correct default — GPG doesn't extend trust just because you imported a key.

$ gpg --import /sec401/labs/4.1/backup/backup-jeffries... && gpg --list-keys

7BAD signature: tamper detected

Verified a signed Bankruptcy.docx from mounted media. GPG reported 'BAD signature from Madison Jeffries'. Either the document or the signature file has been altered since it was signed. In a real workflow this is the point where you stop reading the file and escalate.

$ gpg --verify /media/sec401/CDROM/Bankruptcy.docx.asc

8Surface metadata with exiftool

Pulled metadata off Bankruptcy.docx. ExifTool reported standard DOCX internals plus Application: Microsoft Office Word, Pages: 2, Total Edit Time: 2982555.3 days — an obviously bogus value that on its own is a tampering indicator. Metadata review complements the cryptographic signal: even without a signature, the edit-time field alone warrants investigation.

$ exiftool /media/sec401/CDROM/Bankruptcy.docx

9Restore from backup, re-verify

Copied the signature backup to the lab folder. First verify attempt passed the .docx instead of the .asc (GPG rejected with 'no valid OpenPGP data found'). Re-ran against the .asc and GPG confirmed 'Good signature from Madison Jeffries' with a GPG WARNING that the key is not certified with a trusted signature — expected, because we haven't signed Jeffries's key with our own to extend trust.

$ cp /media/sec401/CDROM/Bankruptcy.docx.asc /sec401/labs/4.1/backup/ && gpg --verify /sec401/labs/4.1/backup/Bankruptcy.docx.asc

Key findings

SHA-256 is content-bound; renaming a file does not change its hash
Single-byte edits produce avalanche-level hash changes
RSA 3072 is the modern GPG default (2048 is no longer recommended)
Detached .asc signatures are the preferred distribution format
Bankruptcy.docx on the lab media fails signature verification (tampered)
Bankruptcy.docx backup copy verifies cleanly (known-good version)
exiftool's 'Total Edit Time: 2982555.3 days' is a tampering red flag on its own

Outcome / Lessons learned

Walked the full integrity chain: hash-based validation for fast change detection, asymmetric signing for authenticity, and a realistic scenario where a tampered document is caught by a BAD signature and the incident resolves by restoring from a signed backup.

In production I'd pin critical vendor public keys in configuration (not just the keyring), establish a web-of-trust or use a keyserver with signed keys, automate verification in CI/CD for any artifact download (release binaries, firmware, scripts), and log verification failures to SIEM so a single BAD signature raises an incident ticket rather than getting retried silently.

Security controls relevant

  • File integrity monitoring (hash-based)
  • Code and document signing (GPG, Sigstore, cosign)
  • Artifact verification in CI/CD pipelines
  • Key management and rotation (HSMs, hardware keys)
  • Trust model enforcement (--trusted-key, --trust-model)
  • Metadata-based tamper indicators (exiftool, oletools)

What I took away from this

The rename vs. sed demo is the cleanest way to internalize what a hash actually is. Most junior analysts can recite 'SHA-256 is a digest' without ever seeing that renaming a file preserves the hash while changing a single ASCII character obliterates it. Once you've watched 66a0...bb35f18 become 5891...6be03 because of a one-byte swap, you stop confusing filename with content integrity.

Signing is where most teams fall down operationally. Generating a key is trivial. Distributing the public key, training every consumer to verify before using, and keeping the private key somewhere that survives laptop loss — that's the actual work. In a production rollout I'd pair GPG with a hardware key (YubiKey in OpenPGP mode) so the private key never sits on disk, and I'd automate verification so humans aren't the last line of defense.

The Bankruptcy.docx scenario is a good teaching moment for two reasons. First, the cryptographic signal (BAD signature) is binary and unambiguous — either the file is the one Jeffries signed or it isn't. Second, the exiftool follow-up shows why you don't rely on any single indicator: metadata, signatures, and hashes each catch different things. In a real investigation, you'd combine all three with a chain-of-custody log before you made a call about authenticity.

Evidence gallery