Cryptography › Module 1 › Lesson 1
What are Hash Functions?
Learn one-way digests, integrity checks, and why hashes are not encryption
Opening
A fingerprint, not a lockbox — hashing verifies bytes; it does not hide them, and it is not a cracking kit.
In Topic 7 you already used hashlib as a defender: SHA-256 of a file you wrote in $HOME/cyberlium-lab, then the same file after an edit, then two hex strings that no longer matched. That was integrity. Same bytes, same digest, every honest machine. Change one character, and the digest looks unrelated — avalanche. People still say “encrypted password” when they mean “hashed password.” Those are not the same operation. Encryption is a lockbox with a key: ciphertext is supposed to come back as plaintext if you hold the key. A cryptographic hash is a one-way digest. You can verify data with it. You cannot (practically) reverse it to get the original. There is no “hash key” to turn SHA-256 hex back into the ISO you downloaded. This lesson is the mechanism under that lab: what a hash function actually computes, why it is deterministic, why it is one-way, why a one-bit flip wrecks the digest, and why hashing is not encryption. You will hash a string and a tiny file you created — still YOUR bytes, still cyberlium-lab, still chmod 600 on notes. You will not invert hashes. You will not download rainbow tables. You will not point hashlib at /etc/shadow or a dump from HaveIBeenPwned. Next lesson names MD5, SHA-1, and SHA-256 so you stop treating “a hash” as one algorithm.
1. Fixed-length digest: any input size in, same-width fingerprint out
A cryptographic hash function takes input of any size — a password string, a 4 KB notes file, a firmware image, an installer — and produces a fixed-length output called a digest (or hash value). SHA-256 always yields 256 bits, usually printed as 64 hexadecimal characters. MD5 yields 128 bits (32 hex chars). The input can be one byte or a gigabyte; the digest width does not grow. That is the first property defenders rely on: you can publish or store a short fingerprint instead of the whole file and still detect change. hashlib.sha256() in Python is this primitive. You feed it bytes (a bytes object, or chunks from a file opened in "rb"), then hexdigest() prints the printable form. You do not hash the filename and call it file integrity. You hash the contents. Text mode would rewrite newlines on some platforms and change the digest — Topic 7 already taught open(path, "rb") for that reason.
Deterministic means the same input always yields the same digest. If it did not, integrity checks would be a coin flip: vendor publishes SHA-256 of an ISO on Monday, you hash your download on Tuesday, and a “good” file would mismatch because the function felt different. Every honest SHA-256 implementation on every honest machine must agree. That is why comparing your local hex to a published hex is a real check — provided you obtained the published hex from a channel you already trust (the vendor site you typed, signed release notes), not from a forum next to a cracked download. Matching hex means the bytes you hashed now equal the bytes that were hashed then. It does not mean the file is safe, signed, or from a vendor. Malware can be hashed too; the digest would just be stable.
2. One-way and avalanche: preimage resistance, and why one bit wrecks the hex
One-way (preimage resistance) means that given a digest, it should be computationally infeasible to find any input that produces it. You are not supposed to “decrypt” SHA-256. There is no inverse function with a key. Brute-force guessing — try inputs until the digest matches — is a different activity, and this course does not turn you into a cracking shop. For integrity of files you own, you never need to invert: you re-hash the file you have and compare. For password storage (next lessons), defenders store a digest so a stolen database does not immediately reveal plaintext; attackers who steal that database may still guess common passwords against a fast unsalted hash — which is why slow salted password hashes exist, and why this module will not send you at dumped hashes or /etc/shadow.
Avalanche means a tiny input change — one bit, one character, one appended newline — should flip about half the digest bits, so the new hex looks unrelated to the old one. You saw this in Topic 7: integrity-demo.txt before and after an edit. If a one-byte change left the digest identical, the function would be useless for integrity: an attacker could patch a binary and keep the published checksum. Collision resistance is the sibling property: it should be hard to find two different inputs with the same digest. Birthday-bound math says collisions exist (the output space is finite). Cryptographic hashes are designed so finding one is impractical for a defender-relevant attacker — except when an algorithm is broken, which is why MD5 and SHA-1 leave the security toolkit in the next lesson. You do not need to produce a collision in this course. You need to know that “the checksum matched” is only as strong as the hash family and the channel that published the expected digest.
3. Hashing is not encryption: no key, no decrypt, no lockbox
Encryption is two-way with a key. Encrypt(plaintext, K) → ciphertext. Decrypt(ciphertext, K) → plaintext. AES in the next module is that model. Anyone can hash; hashing is not a confidentiality control by itself. If you SHA-256 a file and email the digest, you did not hide the file. You produced a fingerprint others can recompute if they have the same bytes. If you SHA-256 a password and store only the hex, you hid the password from casual reading, but you did not encrypt it: there is no key to reverse the digest. Call it a stored verifier, not “encrypted password.” Confusing the two leads to bad designs: people “encrypt” passwords with SHA-256 and think a stolen database is harmless, or they treat a hash as a secret that must never be published — while vendor checksums are supposed to be public so you can check a download.
Use hashing when the job is verify or store-a-verifier: file integrity, commit IDs, password storage (with the password-hash family, not raw SHA-256 — Lesson 3). Use encryption when the job is hide bytes from someone who should not read them, and you have a key-management story. Do not “encrypt” a file by hashing it. Do not “hash” a file by running AES. Do not invent a homemade mix of the two from a blog snippet. Topic 7’s hash_file.py was integrity. This lesson names the properties. Module 2 will name AES. Keep the verbs separate in notes you will actually reread.
4. Integrity in practice: vendor checksums and YOUR lab files — same primitive
The defender habit is: obtain expected SHA-256 from a trusted channel, hash the bytes you have, compare as strings. Mismatch → do not run the installer. Match → the bytes equal the published bytes, not “this is malware-free.” Inside the lab, you do not need a vendor ISO. You hash a file you wrote, edit it, hash again, and write both hexes plus MATCH/DIFFER. That is enough to feel avalanche and determinism. Carry Topic 7’s rules: chunked update so large files fit in RAM, "rb", hexdigest(), notes in $HOME/cyberlium-lab, chmod 600. Empty notes fail. Notes that contain other people’s hashes, shadow lines, or a paste from a breach dump fail ethics even if SHA-256 ran. You may hash every file in cyberlium-lab because you created that tree. You may not hash a classmate’s disk “to see.”
5. Wrong vs right: cracking shop vs one-way fingerprints of bytes you own
Worked failure — same hashlib.sha256, opposite job. Right never inverts dumps, never hashes /etc/shadow, never treats a digest as ciphertext.
Wrong
Call hashing “encryption” and store SHA-256(password) as if a stolen database were harmless. Download rainbow tables. Point hashlib at /etc/shadow or a HaveIBeenPwned dump. Try to invert a hex to plaintext and call the lesson complete only if you recovered someone else’s secret. Hash a coworker’s files. Skip the lab folder and write digests into a world-readable Downloads folder. Treat Topic 8 as a hashcat shop.
Right
Treat a hash as a one-way fixed-size fingerprint: deterministic, avalanche, not reversible with a key. Hash a string and a file you created under $HOME/cyberlium-lab. Record hexes and the sentence “hashing is not encryption.” chmod 600 the notes. Integrity of YOUR bytes — same primitive as Topic 7. Next: MD5, SHA-1, SHA-256 — which families are still fit for signatures and checksums.
6. Hands-on: hashlib of YOUR string and YOUR file, then lock the notes
On a computer you own, create the lab directory if it is missing, write a tiny text file you authored, print SHA-256 of a known string and of that file’s bytes. Change one character in the file, hash again, confirm the digest moved. Fill hash-functions-notes.txt with both hexes, the avalanche observation, and “hashing ≠ encryption.” Do not add a password list to make it “more crypto.” Do not hash /etc/passwd “because it is a file.” chmod 600 the script, the demo file, and the notes.
Command guide
hash_functions_lab.py — SHA-256 of YOUR string and YOUR file (integrity, not cracking)
DEFENSIVE. Integrity fingerprints of bytes YOU created. Hashing is NOT encryption. NOT a cracker. NOT /etc/shadow.
Command — copy this
mkdir -p "$HOME/cyberlium-lab" cd "$HOME/cyberlium-lab"
Command — copy this
cat > hash_functions_lab.py << 'PY'
import hashlib
from pathlib import Path
lab = Path.home() / "cyberlium-lab"
sample = lab / "hash-functions-demo.txt"
sample.write_text("cyberlium hash lesson — before edit
", encoding="utf-8")
print("string sha256:", hashlib.sha256(b"cyberlium").hexdigest())
print("file before :", hashlib.sha256(sample.read_bytes()).hexdigest())
sample.write_text("cyberlium hash lesson — AFTER one-line edit
", encoding="utf-8")
print("file after :", hashlib.sha256(sample.read_bytes()).hexdigest())
print("avalanche: after hex should differ from before")
print("not encryption: no key, cannot decrypt these hexes back to the file")
PYCommand — copy this
python3 hash_functions_lab.py || python hash_functions_lab.py
Command — copy this
NOTES="$HOME/cyberlium-lab/hash-functions-notes.txt"
{
echo "=== HASH FUNCTIONS (integrity, not cracking) ==="
echo "string_input: cyberlium"
echo "string_sha256:"
echo "file: hash-functions-demo.txt"
echo "digest_before:"
echo "digest_after:"
echo "compare: DIFFER (expected after edit)"
echo "properties: deterministic, one-way, avalanche, fixed length"
echo "hashing_is_not_encryption: no key to reverse a digest"
echo "ethics: my files only; no shadow; no dumps; no rainbow tables"
} > "$NOTES"Command — copy this
chmod 600 "$HOME/cyberlium-lab/hash_functions_lab.py" \
"$HOME/cyberlium-lab/hash-functions-demo.txt" \
"$NOTES"Windows without chmod: WSL/Git Bash, or restrict files in your profile.
NEVER: python3 hash_functions_lab.py /etc/shadow NEVER: curl a rainbow table NEVER: paste other people's hashes into the notes
Mission: hash-functions-notes.txt in cyberlium-lab (mode 600)
1) In your own words, list the four properties: deterministic, one-way, avalanche, fixed length — and write the sentence hashing is not encryption (no key to reverse a digest). 2) Run hash_functions_lab.py (or equivalent) on YOUR machine so $HOME/cyberlium-lab/hash-functions-notes.txt holds string SHA-256, before/after file hexes, and MATCH/DIFFER; chmod 600 script, demo file, and notes. 3) Carry Topic 7: hashlib fingerprints files you own. Never invert. Never hash /etc/shadow, dumped databases, or anyone else’s files. No rainbow tables.
Stuck? Ask Cyberlium AI Mentor
If “hashing is just weak encryption” still feels true, ask for a hint — not an inverter. Try: "Hint only: why is SHA-256 a one-way fixed-size fingerprint with avalanche, why matching a vendor digest is integrity not confidentiality, and why I must not hash /etc/shadow or download rainbow tables for this lesson?" You still fill the notes. No cracking. No other people’s hashes. No live secrets in the file.
You now treat a cryptographic hash as a one-way, deterministic, fixed-length fingerprint with avalanche — useful for integrity of bytes you are allowed to touch, useless as a lockbox, forbidden as a cracking shop. Topic 7’s hashlib lab was this primitive in Python; this lesson named the properties. Next — MD5, SHA-1, SHA-256 — you will compare legacy families that lost collision resistance for signatures and certificates with SHA-256 as the default integrity hash, and you will run openssl dgst on a file you own. Password hashing stays a different family until the lesson after that.
Knowledge Check
APPLY: A teammate says the SHA-256 of an ISO is “encryption so nobody can steal the image,” then wants to hash /etc/shadow “to practice reversing.” What is a hash, and what do you do?
Multiple choice
Knowledge Check
APPLY: You hashed hash-functions-demo.txt, changed one line, hashed again. Digests differed. True or False: that avalanche means hashing equals encryption, so you should download rainbow tables to “decrypt” the after hex.
True or False
Knowledge Check
APPLY: You need to confirm a Linux ISO you downloaded. Which pairing matches the mechanism, and where do lab notes live?
Multiple choice