Encoding vs Encryption vs Hashing
TL;DR: Encoding transforms data format (reversible, no key). Encryption protects data confidentiality (reversible, requires key). Hashing creates a fingerprint (one-way, no reversal). Developers often confuse these - that’s where vulnerabilities live.
Table of Contents
Open Table of Contents
Quick Reference
At a Glance
| Property | Encoding | Encryption | Hashing |
|---|
| Purpose | Data format conversion | Confidentiality | Integrity/verification |
| Reversible | Yes (no key needed) | Yes (key required) | No (one-way) |
| Key required | No | Yes | No |
| Output length | Variable | Variable (usually ≥ input) | Fixed length |
| Security | None | Strong (if done right) | Strong (if done right) |
| Use case | Data transport | Secret storage | Password storage |
Common Examples
| Type | Examples |
|---|
| Encoding | Base64, URL encoding, HTML entities, Hex, ASCII |
| Encryption | AES, RSA, ChaCha20, 3DES |
| Hashing | MD5, SHA-1, SHA-256, bcrypt, Argon2 |
Quick Identification
| If you see… | It’s probably… |
|---|
SGVsbG8gV29ybGQ= | Base64 encoding |
%20%3C%3E | URL encoding |
<> | HTML entity encoding |
48656c6c6f | Hex encoding |
U2FsdGVkX1... | Encrypted (OpenSSL) |
5d41402abc4b2a76b9719d911017c592 (32 chars) | MD5 hash |
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d (40 chars) | SHA-1 hash |
$2a$10$... | bcrypt hash |
Why This Matters for Pentesters
Common Vulnerabilities from Confusion
| Mistake | Vulnerability | Example |
|---|
| Base64 “encryption” | Data exposure | API tokens in Base64 |
| MD5 for passwords | Easy cracking | Legacy password storage |
| Encryption without auth | Tampering | CBC bit-flipping |
| Static encryption keys | Key exposure | Hardcoded keys in source |
| Weak hashing | Rainbow tables | Unsalted SHA-1 passwords |
Real-World Breaches
| Incident | Issue | Impact |
|---|
| Adobe (2013) | 3DES ECB + same key | 153M passwords exposed |
| LinkedIn (2012) | Unsalted SHA-1 | 117M passwords cracked |
| Ashley Madison (2015) | bcrypt (good!) + MD5 tokens | Tokens cracked |
| Yahoo (2013) | MD5 passwords | 3B accounts |
The Key Differences
Visual Comparison
┌─────────────────────────────────────────────────────────────────────┐
│ ENCODING │
│ │
│ "Hello" ───────► "SGVsbG8=" ───────► "Hello" │
│ encode decode │
│ │
│ • Anyone can decode │
│ • No secret/key needed │
│ • NOT for security │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ ENCRYPTION │
│ │
│ "Hello" ──────────► "x#$%^&" ──────────► "Hello" │
│ encrypt decrypt │
│ (with key) (with key) │
│ │
│ • Only key holder can decrypt │
│ • Key must be kept secret │
│ • FOR confidentiality │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ HASHING │
│ │
│ "Hello" ──────────► "185f8db32271..." │
│ hash │
│ │
│ "Hello" ──────────► "185f8db32271..." (same input = same hash)│
│ │
│ • Cannot reverse to get "Hello" │
│ • Same input always gives same output │
│ • FOR verification/integrity │
└─────────────────────────────────────────────────────────────────────┘
Decision Tree
Do you need to get the original data back?
│
├── NO ─────────► Use HASHING
│ (passwords, integrity checks)
│
└── YES ──► Does it need to be kept secret?
│
├── NO ─────────► Use ENCODING
│ (transport, format conversion)
│
└── YES ─────────► Use ENCRYPTION
(sensitive data storage/transmission)
Encoding Deep Dive
TL;DR: Encoding converts data to a different format for safe transport. It’s NOT security - anyone can decode it.
Why Encoding Exists
| Problem | Encoding Solution |
|---|
| Binary data in text protocols | Base64 |
| Special chars in URLs | URL encoding |
| Special chars in HTML | HTML entities |
| Human-readable binary | Hex, ASCII |
| Unicode in ASCII systems | UTF-8, UTF-16 |
Base64 Encoding
Converts binary to text using 64 characters (A-Z, a-z, 0-9, +, /).
Original: Hello World
Binary: 01001000 01100101 01101100 01101100 01101111 ...
Base64: SGVsbG8gV29ybGQ=
Characteristics:
- Output is ~33% larger than input
- Uses
= padding at end (0-2 chars)
- Alphabet:
A-Za-z0-9+/
- URL-safe variant uses
-_ instead of +/
| Attack | Detect | Defend |
|---|
| Decode “secret” tokens | Check for Base64 patterns | Never use Base64 for secrets |
| Decode API credentials | Monitor for exposed creds | Use proper encryption |
| Bypass filters (XSS) | Detect encoding obfuscation | Decode before validation |
Commands
# Encode to Base64
echo -n "Hello World" | base64
# SGVsbG8gV29ybGQ=
# Decode from Base64
echo "SGVsbG8gV29ybGQ=" | base64 -d
# Hello World
# Python
python3 -c "import base64; print(base64.b64encode(b'Hello').decode())"
python3 -c "import base64; print(base64.b64decode('SGVsbG8=').decode())"
# URL-safe Base64
python3 -c "import base64; print(base64.urlsafe_b64encode(b'Hello').decode())"
# CyberChef (online)
# https://gchq.github.io/CyberChef/
URL Encoding (Percent Encoding)
Encodes special characters for use in URLs.
Original: Hello World!
Encoded: Hello%20World%21
Common Encodings:
| Character | URL Encoded | Name |
|---|
| (space) | %20 or + | Space |
< | %3C | Less than |
> | %3E | Greater than |
" | %22 | Quote |
' | %27 | Single quote |
/ | %2F | Slash |
? | %3F | Question mark |
& | %26 | Ampersand |
= | %3D | Equals |
# | %23 | Hash |
\n | %0A | Newline |
\r | %0D | Carriage return |
| Attack | Detect | Defend |
|---|
| Double URL encoding bypass | Check for %25 patterns | Decode recursively |
Path traversal (%2e%2e%2f) | Log decoded paths | Normalize before check |
| XSS filter bypass | Detect encoding variations | Decode before validation |
Commands
# URL encode
python3 -c "import urllib.parse; print(urllib.parse.quote('Hello World!'))"
# Hello%20World%21
# URL decode
python3 -c "import urllib.parse; print(urllib.parse.unquote('Hello%20World%21'))"
# Hello World!
# Double encoding
python3 -c "import urllib.parse; print(urllib.parse.quote(urllib.parse.quote('../etc/passwd')))"
# %252e%252e%252fetc%252fpasswd
# Using curl
curl -G --data-urlencode "param=Hello World" "http://example.com"
HTML Entity Encoding
Encodes special characters for safe display in HTML.
Original: <script>alert('XSS')</script>
Encoded: <script>alert('XSS')</script>
Common Entities:
| Character | Named Entity | Numeric Entity |
|---|
< | < | < |
> | > | > |
" | " | " |
' | ' | ' |
& | & | & |
| (space) | |   |
| Attack | Detect | Defend |
|---|
| XSS via numeric entities | Check for &# patterns | Proper output encoding |
| Filter bypass with obscure entities | Detect unusual entities | Decode before validation |
| Mixed encoding attacks | Log encoding patterns | Use security libraries |
Commands
# Python HTML encode
python3 -c "import html; print(html.escape('<script>alert(1)</script>'))"
# <script>alert(1)</script>
# Python HTML decode
python3 -c "import html; print(html.unescape('<script>'))"
# <script>
# PHP
php -r "echo htmlentities('<script>');"
php -r "echo html_entity_decode('<script>');"
Hex Encoding
Represents bytes as hexadecimal values.
Original: Hello
Hex: 48656c6c6f
| Attack | Detect | Defend |
|---|
| Obfuscate payloads | Detect hex patterns | Decode before processing |
| Bypass WAF rules | Monitor for long hex strings | Normalize input |
| SQLi via hex strings | Log unusual encodings | Input validation |
Commands
# Hex encode
echo -n "Hello" | xxd -p
# 48656c6c6f
# Hex decode
echo "48656c6c6f" | xxd -r -p
# Hello
# Python
python3 -c "print('Hello'.encode().hex())"
python3 -c "print(bytes.fromhex('48656c6c6f').decode())"
# SQL hex encoding (for SQLi)
# SELECT * FROM users WHERE name = 0x61646d696e (admin)
Unicode Encoding
Different representations of Unicode characters.
Character: é
UTF-8: c3 a9 (2 bytes)
UTF-16: 00e9 (2 bytes)
UTF-32: 000000e9 (4 bytes)
URL: %C3%A9
HTML: é or é
| Attack | Detect | Defend |
|---|
| Homograph attacks (look-alike chars) | Check for mixed scripts | Normalize Unicode |
| Filter bypass via UTF-8 overlong | Detect invalid UTF-8 | Reject invalid encoding |
| Directory traversal via Unicode | Log unusual paths | Use canonical paths |
Commands
# Check encoding
file -bi document.txt
# Convert encodings
iconv -f UTF-8 -t UTF-16 input.txt > output.txt
# Python Unicode
python3 -c "print('\u003cscript\u003e')"
# <script>
# Unicode normalization
python3 -c "import unicodedata; print(unicodedata.normalize('NFC', 'café'))"
Encryption Deep Dive
TL;DR: Encryption makes data unreadable without the key. Symmetric uses one key; asymmetric uses a key pair.
Symmetric vs Asymmetric
┌────────────────────────────────────────────────────────────────┐
│ SYMMETRIC ENCRYPTION │
│ │
│ Same key for encrypt and decrypt │
│ │
│ Plaintext ──[Key]──► Ciphertext ──[Key]──► Plaintext │
│ │
│ Examples: AES, ChaCha20, 3DES │
│ Use: Bulk data encryption, disk encryption │
│ Speed: Fast │
│ Challenge: Key distribution │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ ASYMMETRIC ENCRYPTION │
│ │
│ Different keys for encrypt and decrypt │
│ │
│ Plaintext ──[Public Key]──► Ciphertext ──[Private Key]──► Plaintext
│ │
│ Examples: RSA, ECC, ElGamal │
│ Use: Key exchange, digital signatures │
│ Speed: Slow │
│ Advantage: No key distribution problem │
└────────────────────────────────────────────────────────────────┘
AES (Advanced Encryption Standard)
The gold standard for symmetric encryption.
Parameters:
- Key sizes: 128, 192, or 256 bits
- Block size: 128 bits (16 bytes)
- Modes: ECB, CBC, CTR, GCM, etc.
Modes Comparison:
| Mode | Security | Use Case | Weakness |
|---|
| ECB | Weak | Never use | Patterns visible |
| CBC | Good | Legacy systems | IV required, padding attacks |
| CTR | Good | Stream-like | Nonce reuse catastrophic |
| GCM | Best | Modern systems | Nonce reuse catastrophic |
ECB vs CBC (Visual):
ECB Mode (BAD): CBC Mode (Good):
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│Block 1│ │Block 1│ │Block 1│ │Block 2│
│ AAAA │ │ AAAA │ │ AAAA │ │ AAAA │
└───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│ Same │ │ Same │ │ Diff │ │ Diff │
│Output!│ │Output!│ │Output │ │Output │
└───────┘ └───────┘ └───────┘ └───────┘
Same input = Same ciphertext Same input = Different ciphertext
(Information leaked!) (Pattern hidden)
| Attack | Detect | Defend |
|---|
| ECB pattern analysis | Check for repeated blocks | Use GCM mode |
| CBC padding oracle | Monitor decryption errors | Use authenticated encryption |
| Key extraction from code | Code review | Use key management service |
| IV/nonce reuse | Log encryption parameters | Generate random IV/nonce |
Commands
# === OpenSSL AES Encryption ===
# Encrypt file (AES-256-CBC)
openssl enc -aes-256-cbc -salt -in plaintext.txt -out encrypted.enc -k password
# Decrypt file
openssl enc -aes-256-cbc -d -in encrypted.enc -out decrypted.txt -k password
# AES-256-GCM (recommended)
openssl enc -aes-256-gcm -salt -in plaintext.txt -out encrypted.enc -k password
# === Python AES ===
# pip install pycryptodome
python3 << 'EOF'
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
key = get_random_bytes(32) # 256-bit key
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(b"Hello World")
print(f"Ciphertext: {ciphertext.hex()}")
print(f"Nonce: {cipher.nonce.hex()}")
print(f"Tag: {tag.hex()}")
EOF
RSA (Rivest-Shamir-Adleman)
Most common asymmetric encryption.
Parameters:
- Key sizes: 2048, 3072, 4096 bits
- Based on: Factoring large primes is hard
Common Uses:
- TLS key exchange
- Digital signatures
- Encrypting symmetric keys
| Attack | Detect | Defend |
|---|
| Weak key size (<2048) | Check certificate | Use 2048+ bit keys |
| Padding oracle (PKCS#1 v1.5) | Monitor decryption errors | Use OAEP padding |
| Timing attacks | Analyze response times | Constant-time operations |
| Common modulus attack | Check for key reuse | Unique keys per system |
Commands
# === Generate RSA Key Pair ===
# Generate private key
openssl genrsa -out private.pem 2048
# Extract public key
openssl rsa -in private.pem -pubout -out public.pem
# === Encrypt/Decrypt ===
# Encrypt with public key
openssl rsautl -encrypt -pubin -inkey public.pem -in plaintext.txt -out encrypted.bin
# Decrypt with private key
openssl rsautl -decrypt -inkey private.pem -in encrypted.bin -out decrypted.txt
# === Examine Keys ===
# View private key components
openssl rsa -in private.pem -text -noout
# View public key
openssl rsa -pubin -in public.pem -text -noout
Common Encryption Mistakes
| Mistake | Why It’s Bad | Correct Approach |
|---|
| ECB mode | Patterns visible | Use GCM mode |
| Hardcoded keys | Key in source code | Use key management |
| Same IV/nonce | Breaks security | Random per encryption |
| No authentication | Tampering possible | Use AEAD (AES-GCM) |
| Home-grown crypto | Likely flawed | Use established libraries |
| MD5/SHA1 for HMAC | Weak hash | Use SHA-256+ |
| Encrypt then MAC | Order matters | Use AEAD or MAC-then-Encrypt |
Hashing Deep Dive
TL;DR: Hashing creates a fixed-size fingerprint of data. Same input = same hash. Used for passwords, integrity, and deduplication.
Hash Properties
| Property | Description | Broken If… |
|---|
| Deterministic | Same input = same output | Not applicable |
| Fixed length | Any input → fixed output | Output varies |
| Pre-image resistant | Can’t find input from hash | Can reverse hash |
| Collision resistant | Can’t find two inputs with same hash | Collisions found |
| Avalanche effect | Small change = completely different hash | Similar hashes |
Hash Comparison
| Algorithm | Output Length | Security | Speed | Use Case |
|---|
| MD5 | 128 bit (32 hex) | Broken | Fast | Checksums only |
| SHA-1 | 160 bit (40 hex) | Weak | Fast | Legacy, avoid |
| SHA-256 | 256 bit (64 hex) | Strong | Fast | General purpose |
| SHA-512 | 512 bit (128 hex) | Strong | Fast | High security |
| bcrypt | 184 bit | Strong | Slow | Passwords |
| Argon2 | Configurable | Strong | Slow | Passwords |
| scrypt | Configurable | Strong | Slow | Passwords |
MD5 (Message Digest 5)
Status: Broken - DO NOT use for security
Input: Hello World
MD5: b10a8db164e0754105b7a99be72e3fe5
Why It’s Broken:
- Collision attacks demonstrated (2004)
- Pre-image attacks feasible for some cases
- Fast = easy to brute force
| Attack | Detect | Defend |
|---|
| Rainbow tables | Check for MD5 patterns | Migrate to bcrypt |
| Collision attacks | Monitor for hash reuse | Use SHA-256+ |
| Brute force | Log cracking attempts | Add salt + iterations |
Commands
# Generate MD5
echo -n "Hello World" | md5sum
# b10a8db164e0754105b7a99be72e3fe5
# Python
python3 -c "import hashlib; print(hashlib.md5(b'Hello World').hexdigest())"
# Crack with hashcat
hashcat -m 0 -a 0 hash.txt wordlist.txt
# Crack with john
john --format=raw-md5 --wordlist=wordlist.txt hash.txt
SHA Family
SHA-1: Weak (collision found 2017)
SHA-256/512: Currently secure
Input: Hello World
SHA-1: 0a4d55a8d778e5022fab701977c5d840bbc486d0
SHA-256: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
SHA-512: 2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d
8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b
| Attack | Detect | Defend |
|---|
| SHA-1 collision | Check for SHA-1 usage | Migrate to SHA-256 |
| Rainbow tables (unsalted) | Monitor for common hashes | Always use salt |
| Length extension | Detect HMAC bypass | Use HMAC, not hash(key+data) |
Commands
# SHA-1
echo -n "Hello World" | sha1sum
# SHA-256
echo -n "Hello World" | sha256sum
# SHA-512
echo -n "Hello World" | sha512sum
# Python
python3 -c "import hashlib; print(hashlib.sha256(b'Hello World').hexdigest())"
# Hashcat modes
# SHA-1: -m 100
# SHA-256: -m 1400
# SHA-512: -m 1700
Password Hashing (bcrypt, Argon2, scrypt)
Why Regular Hashes Are Bad for Passwords:
- Too fast = easy to brute force
- GPUs crack billions per second
Password Hashes Are:
- Intentionally slow (configurable)
- Include salt automatically
- Designed to resist GPU attacks
bcrypt Hash Format:
$2a$10$N9qo8uLOickgx2ZMRZoMye.IjqQBrkHBSgSst/w/cP/LLyZLxPJhO
│ │ │ │ │
│ │ │ └── 22 char salt ─────────────────┘
│ │ └── Cost factor (2^10 = 1024 iterations)
│ └── Version (2a, 2b, 2y)
└── Algorithm identifier
| Attack | Detect | Defend |
|---|
| Brute force | Monitor failed logins | Use cost factor 12+ |
| Rainbow tables | N/A (salt prevents) | bcrypt includes salt |
| GPU cracking | Log cracking duration | Use Argon2id |
Commands
# Generate bcrypt hash (Python)
python3 -c "import bcrypt; print(bcrypt.hashpw(b'password', bcrypt.gensalt(rounds=12)))"
# Verify bcrypt
python3 << 'EOF'
import bcrypt
stored = b'$2b$12$...' # stored hash
if bcrypt.checkpw(b'password', stored):
print("Match!")
EOF
# Generate Argon2 hash
python3 -c "from argon2 import PasswordHasher; ph = PasswordHasher(); print(ph.hash('password'))"
# Hashcat bcrypt
hashcat -m 3200 -a 0 hash.txt wordlist.txt
# John the Ripper bcrypt
john --format=bcrypt hash.txt
HMAC (Hash-based Message Authentication Code)
Combines hash with secret key for authentication.
HMAC-SHA256(key, message) = hash(key ⊕ opad || hash(key ⊕ ipad || message))
Used For:
- API authentication
- Message integrity
- JWT signatures
| Attack | Detect | Defend |
|---|
| Weak key | Check key entropy | Use 256+ bit keys |
| Timing attack | Analyze comparison time | Constant-time compare |
| Key in URL | Monitor for key leakage | Use headers, not URLs |
Commands
# Generate HMAC-SHA256
echo -n "message" | openssl dgst -sha256 -hmac "secret_key"
# Python
python3 -c "import hmac; import hashlib; print(hmac.new(b'key', b'message', hashlib.sha256).hexdigest())"
# Verify HMAC
python3 << 'EOF'
import hmac
import hashlib
def verify_hmac(key, message, signature):
expected = hmac.new(key, message, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature) # Timing-safe!
print(verify_hmac(b'key', b'message', 'expected_sig'))
EOF
Common Mistakes and Vulnerabilities
Testing Checklist
Vulnerability Matrix
| Finding | Severity | Impact |
|---|
| Base64 “encryption” | High | Data exposure |
| MD5 passwords | High | Easy cracking |
| SHA1 passwords (unsalted) | High | Rainbow tables |
| ECB mode encryption | Medium | Pattern leakage |
| Hardcoded keys | Critical | Full compromise |
| Weak bcrypt cost (< 10) | Medium | Faster cracking |
| Missing salt | High | Rainbow tables |
| Encryption without MAC | Medium | Data tampering |
Identifying Data Types
By Length
| Length (hex chars) | Possible Type |
|---|
| 32 | MD5, NTLM |
| 40 | SHA-1 |
| 56 | SHA-224 |
| 64 | SHA-256, SHA3-256 |
| 96 | SHA-384 |
| 128 | SHA-512, SHA3-512 |
By Pattern
| Pattern | Type |
|---|
$1$... | MD5 crypt |
$2a$..., $2b$..., $2y$... | bcrypt |
$5$... | SHA-256 crypt |
$6$... | SHA-512 crypt |
$argon2id$... | Argon2 |
$scrypt$... | scrypt |
{SHA}... | LDAP SHA |
{SSHA}... | LDAP salted SHA |
Ends with = or == | Base64 |
%XX format | URL encoding |
# hashid
hashid 'b10a8db164e0754105b7a99be72e3fe5'
# [+] MD5
# hash-identifier
hash-identifier
# Enter hash: ...
# hashcat --identify
hashcat --identify hash.txt
# Online: hashes.com/en/tools/hash_identifier
Cracking and Breaking
Hash Cracking Workflow
1. Identify hash type
│
▼
2. Check online databases
- crackstation.net
- hashes.com
- cmd5.org
│
▼
3. Try common passwords
- rockyou.txt
- common wordlists
│
▼
4. Rule-based attack
- hashcat rules
- john rules
│
▼
5. Mask attack (patterns)
- ?d?d?d?d?d?d (6 digits)
- ?u?l?l?l?l?d?d (Ulllld)
│
▼
6. Brute force (last resort)
Hashcat Cheat Sheet
| Hash Type | Mode | Example |
|---|
| MD5 | 0 | hashcat -m 0 |
| SHA1 | 100 | hashcat -m 100 |
| SHA256 | 1400 | hashcat -m 1400 |
| SHA512 | 1700 | hashcat -m 1700 |
| bcrypt | 3200 | hashcat -m 3200 |
| NTLM | 1000 | hashcat -m 1000 |
| MySQL 5 | 300 | hashcat -m 300 |
| Argon2 | 28000 | hashcat -m 28000 |
Cracking Commands
# === Hashcat ===
# Dictionary attack
hashcat -m 0 -a 0 hashes.txt rockyou.txt
# With rules
hashcat -m 0 -a 0 hashes.txt rockyou.txt -r rules/best64.rule
# Mask attack (8 char, lowercase + digits)
hashcat -m 0 -a 3 hashes.txt ?l?l?l?l?l?d?d?d
# Combination attack
hashcat -m 0 -a 1 hashes.txt wordlist1.txt wordlist2.txt
# Show cracked
hashcat -m 0 hashes.txt --show
# === John the Ripper ===
# Auto-detect and crack
john hashes.txt
# With wordlist
john --wordlist=rockyou.txt hashes.txt
# With rules
john --wordlist=rockyou.txt --rules hashes.txt
# Show cracked
john --show hashes.txt
# === Online Databases ===
# CrackStation
curl -X POST -d "hash=b10a8db164e0754105b7a99be72e3fe5" https://crackstation.net/
# hashes.com API (requires account)
Encoding/Decoding
| Tool | Purpose | Install |
|---|
| base64 | Base64 encode/decode | Built-in |
| xxd | Hex encode/decode | apt install xxd |
| CyberChef | All encodings | gchq.github.io/CyberChef |
| urlencode | URL encode | Python urllib |
Encryption
| Tool | Purpose | Install |
|---|
| openssl | All crypto operations | Built-in |
| gpg | PGP encryption | Built-in |
| age | Modern encryption | apt install age |
| ccrypt | Simple file encryption | apt install ccrypt |
Hashing
| Tool | Purpose | Install |
|---|
| hashcat | GPU hash cracking | apt install hashcat |
| john | CPU hash cracking | apt install john |
| hashid | Hash identification | pip install hashid |
| hash-identifier | Hash identification | apt install hash-identifier |
Online Resources
| Resource | URL | Use |
|---|
| CrackStation | crackstation.net | Hash lookup |
| hashes.com | hashes.com | Hash lookup |
| CyberChef | gchq.github.io/CyberChef | All encoding |
| dCode | dcode.fr | Many encodings |
Practice Labs
Beginner
| Resource | Focus | Link |
|---|
| CryptoHack | Crypto fundamentals | cryptohack.org |
| TryHackMe - Hashing | Hash basics | tryhackme.com |
| OverTheWire - Krypton | Classical crypto | overthewire.org |
| Resource | Focus |
|---|
| PicoCTF | CTF crypto challenges |
| Cryptopals | Practical crypto attacks |
| Root Me | Crypto challenges |
Practice Exercises
-
Identify the encoding:
SGVsbG8gV29ybGQ=
48656c6c6f
%48%65%6c%6c%6f
-
Identify the hash:
5d41402abc4b2a76b9719d911017c592
$2a$10$N9qo8uLOickgx2ZMRZoMye...
2c74fd17edafd80e8447b0d46741ee24...
-
Crack these hashes:
5f4dcc3b5aa765d61d8327deb882cf99 (MD5)
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 (SHA1)
Glossary
| Term | Definition |
|---|
| AEAD | Authenticated Encryption with Associated Data |
| AES | Advanced Encryption Standard (symmetric) |
| Asymmetric | Different keys for encrypt/decrypt |
| Base64 | Binary-to-text encoding using 64 characters |
| bcrypt | Password hashing algorithm (slow, salted) |
| Block cipher | Encrypts fixed-size blocks |
| CBC | Cipher Block Chaining mode |
| Collision | Two inputs producing same hash |
| ECB | Electronic Codebook mode (insecure) |
| GCM | Galois/Counter Mode (AEAD) |
| Hash | One-way function producing fixed-size output |
| HMAC | Hash-based Message Authentication Code |
| IV | Initialization Vector (for block ciphers) |
| Nonce | Number used once (for stream ciphers) |
| Padding | Adding bytes to fill block size |
| Pre-image | Finding input from hash output |
| Rainbow table | Precomputed hash-to-password lookup |
| RSA | Asymmetric encryption algorithm |
| Salt | Random data added before hashing |
| SHA | Secure Hash Algorithm family |
| Stream cipher | Encrypts byte-by-byte |
| Symmetric | Same key for encrypt/decrypt |
What’s Next?
Now that you understand encoding, encryption, and hashing:
| Topic | Description | Link |
|---|
| TLS/SSL Handshake | How encryption is negotiated | TLS Deep Dive |
| PKI & Certificates | How trust is established | Coming Soon |
| Authentication Flows | How auth uses these concepts | Auth Flows Guide |
| Web App Pentesting | Apply knowledge to web testing | Web App Pentesting Guide |
Summary
Understanding encoding, encryption, and hashing is fundamental:
| Concept | Key Point | Pentester Focus |
|---|
| Encoding | Format conversion, not security | Decode “secrets”, bypass filters |
| Encryption | Confidentiality with keys | Find weak ciphers, key exposure |
| Hashing | One-way fingerprint | Crack weak hashes, identify algorithms |
Remember:
- Encoding ≠ Security
- MD5/SHA1 passwords = easy win
- Look for hardcoded keys
- Check for proper salt/iterations
- ECB mode = visible patterns
Found this guide helpful? Check out the other posts in the SecureKhan penetration testing series.