Hashlash: MD5, SHA-256, bcrypt, Argon2
Hash funksiyalar, ularning xususiyatlari, MD5/SHA/bcrypt/Argon2 farqlari, Rainbow Table hujumi, Tuz (Salt) qo'llash, HMAC va parollarni xavfsiz saqlash.
1 Hash Funksiya Nima?
Kriptografik Hash Xususiyatlari
Pre-image Resistance (Bir tomonlama)
H(x) = h berilsa, x topish hisoblash jihatdan imkonsiz
Second Pre-image Resistance
x berilsa, H(x')=H(x) bo'lgan x'≠x topish imkonsiz
Collision Resistance
H(x)=H(y) bo'lgan x≠y juftini topish imkonsiz
Avalanche Effekti
1-bit o'zgarish hash ning ~50% bitlarini o'zgartiradi
Hash vs Shifrlash vs Encoding
| Xususiyat | Hash | Shifr | Encoding |
|---|---|---|---|
| Teskari? | Yo'q | Ha (kalit) | Ha |
| Kalit kerak? | Yo'q | Ha | Yo'q |
| O'lcham | Qat'iy | ~Kirish | ~Kirish |
| Maqsad | Yaxlitlik | Maxfiylik | Format |
| Misol | SHA-256 | AES | Base64 |
2 Hash Algoritmlar Taqqoslanishi
| Algoritm | Chiqish | Tezlik | Koliziya | Xavfsizlik | Ishlatish |
|---|---|---|---|---|---|
| MD5 | 128-bit (32 hex) | Juda tez | Topilgan (2004) | BUZILGAN | Non-cryptographic checksum |
| SHA-1 | 160-bit (40 hex) | Tez | SHAttered (2017) | DEPRECATED | Git (legacy), ishlatmang |
| SHA-256 | 256-bit (64 hex) | O'rtacha | Topilmagan | XAVFSIZ | TLS, JWT, Bitcoin |
| SHA-512 | 512-bit (128 hex) | O'rtacha | Topilmagan | XAVFSIZ | Fayl yaxlitligi |
| SHA-3 | 224/256/384/512-bit | Sekin | Topilmagan | XAVFSIZ | SHA-256 muqobili, Keccak |
| BLAKE2 | 256/512-bit | Juda tez | Topilmagan | XAVFSIZ | Argon2 ichida, WireGuard |
import hashlib
# Turli hash algoritmlar
message = b"CTF{hash_me}"
print("MD5: ", hashlib.md5(message).hexdigest())
print("SHA-1: ", hashlib.sha1(message).hexdigest())
print("SHA-256:", hashlib.sha256(message).hexdigest())
print("SHA-512:", hashlib.sha512(message).hexdigest())
print("SHA3-256:", hashlib.sha3_256(message).hexdigest())
print("BLAKE2b:", hashlib.blake2b(message).hexdigest())
# Avalanche effektini ko'rish
a = hashlib.sha256(b"hello").hexdigest()
b = hashlib.sha256(b"Hello").hexdigest() # Faqat 1 harf farq
print(f"Mos bitlar: {sum(x==y for x,y in zip(a,b))}/{len(a)}")
# ~0 ta mos bit — to'liq farq!
3 Parollarni Xavfsiz Saqlash
Nima uchun MD5/SHA-256 parol uchun yaramaydi?
MD5 va SHA-256 tez ishlash uchun mo'ljallangan — GPU da sekundiga milliardlab hash hisoblash mumkin. Parol hashlash uchun esa ataylab sekin bo'lishi kerak.
Parol KDF (Key Derivation Function) Taqqoslash
Cost factor (work factor) — 2^cost ta iteratsiya. 1999-yil, hali xavfsiz. Xotira: 4 KB.
CPU + Xotira intensiv. N (CPU), r (xotira), p (parallel) parametrlar. GPU bilan hujumga chidamli.
Password Hashing Competition g'olibi (2015). Side-channel + GPU hujumlariga chidamli. OWASP tavsiyasi.
NIST tavsiya. Iteratsiya soni >600,000 (SHA-256). FIPS 140-2 uchun zarur.
import bcrypt
from argon2 import PasswordHasher
import hashlib, os
# ============================
# bcrypt
# ============================
password = b"mysecretpassword"
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
print(hashed) # $2b$12$...
# Tekshirish (timing-safe)
bcrypt.checkpw(password, hashed) # True
# ============================
# Argon2id (eng yaxshi tanlov)
# ============================
ph = PasswordHasher(
time_cost=3, # iteratsiya
memory_cost=65536,# 64MB xotira
parallelism=2, # parallel iplar
hash_len=32,
)
h = ph.hash("mypassword")
ph.verify(h, "mypassword") # True yoki VerifyMismatchError
# ============================
# PBKDF2-HMAC-SHA256
# ============================
salt = os.urandom(32)
key = hashlib.pbkdf2_hmac(
'sha256', password, salt,
iterations=600_000 # NIST 2023 min
)
# NOTO'G'RI (hech qachon bunday qilmang!)
# bad_hash = hashlib.md5(password).hexdigest()
# bad_hash = hashlib.sha256(password).hexdigest()
4 Rainbow Table Hujumi va Tuz (Salt)
Rainbow Table nima?
Rainbow table — keng tarqalgan parollar va ularning hashlarining oldindan hisoblangan ro'yxati. Xotirada saqlangan hash → parol xaritalash.
| Parol | MD5 Hash |
|---|---|
| password | 5f4dcc3b5aa7... |
| 123456 | e10adc3949ba... |
| qwerty | d8578edf8458... |
| admin | 21232f297a57... |
RockYou wordlist: 14 million parol. MD5 rainbow table: TB gacha — lekin darhol qidirish!
Salt qanday himoya qiladi?
Salt — har bir foydalanuvchi uchun tasodifiy qo'shimcha ma'lumot. Bir xil parol → har xil hash.
// Ikki foydalanuvchi, bir xil parol: "password"
User1 salt: "a1b2c3"
bcrypt("password" + "a1b2c3") = $2b$12$a1...xyz
User2 salt: "x9y8z7"
bcrypt("password" + "x9y8z7") = $2b$12$x9...abc
→ Butunlay boshqa hashlar!
Rainbow table ishlamaydi — har biri uchun alohida table kerak.
5 HMAC (Hash-based Message Authentication Code)
HMAC — hash funksiya + sir kalit birlashmasidir. Xabarning ham yaxlitligini, ham autentikligini ta'minlaydi. Odatiy hash faqat yaxlitlik (kim o'zgartirgani ko'rinmaydi) beradi — HMAC esa autentlik ham qo'shadi.
HMAC Formulasi
Ichki va tashqi padding bilan:
HMAC(K, M) =
H( (K ⊕ opad) || H( (K ⊕ ipad) || M ) )
K = kalit, M = xabar
opad = 0x5c × blok_size
ipad = 0x36 × blok_size
Qayerda ishlatiladi:
• JWT (JSON Web Token) — HS256, HS512
• API autentifikatsiyasi (AWS, GitHub)
• TLS xabar autentifikatsiyasi
• TOTP (Google Authenticator)
import hmac, hashlib
# HMAC yaratish
key = b"super_secret_key"
message = b"Hello, World!"
mac = hmac.new(key, message, hashlib.sha256)
print(mac.hexdigest())
# Tekshirish (timing-safe compare!)
def verify_hmac(key, message, received_mac):
expected = hmac.new(key, message, hashlib.sha256).digest()
# hmac.compare_digest — timing attack dan himoya
return hmac.compare_digest(expected, received_mac)
# JWT misol (qo'lda)
import base64, json
def create_jwt(payload: dict, secret: str) -> str:
header = base64.b64encode(json.dumps(
{"alg": "HS256", "typ": "JWT"}).encode()
).rstrip(b'=')
payload_b = base64.b64encode(
json.dumps(payload).encode()
).rstrip(b'=')
unsigned = header + b'.' + payload_b
sig = hmac.new(secret.encode(), unsigned, hashlib.sha256).digest()
sig_b = base64.b64encode(sig).rstrip(b'=')
return (unsigned + b'.' + sig_b).decode()
jwt_token = create_jwt({"user": "alice"}, "mysecret")
print(jwt_token)
6 CTF: Hash Cracking
Hash Tanish (Identification)
// 32 hex → MD5
5f4dcc3b5aa765d61d8327deb882cf99
// 40 hex → SHA-1
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
// 64 hex → SHA-256
5e884898da28047151d0e56f8dc629277...ab1
// $2b$12$... → bcrypt
$2b$12$LQv3c1yqBWVHxkd0LHAkCO...
// $argon2id$... → Argon2
$argon2id$v=19$m=65536,t=3,p=2...
CTF Hash Cracking Vositalari
hashcat (GPU-based)
# MD5 dictionary attack
hashcat -m 0 hash.txt rockyou.txt
# SHA-256 brute force (6 raqam)
hashcat -m 1400 hash.txt -a 3 ?d?d?d?d?d?d
# bcrypt (m=3200)
hashcat -m 3200 hash.txt wordlist.txt
john the ripper
john --format=raw-md5 hash.txt
john --wordlist=rockyou.txt hash.txt
john --show hash.txt
Online vositalar
crackstation.net — 15 milliard hash DB
hashes.com — MD5/SHA-1/SHA-256 tanlash
hash-identifier — hash turini aniqlash
import hashlib
# CTF: Dictionary attack
def crack_md5(target_hash, wordlist_file):
with open(wordlist_file) as f:
for line in f:
word = line.strip()
h = hashlib.md5(word.encode()).hexdigest()
if h == target_hash:
print(f"Topildi: {word}")
return word
return None
# CTF: Hash turini aniqlash
def identify_hash(h):
h = h.strip()
if h.startswith('$2b$') or h.startswith('$2a$'):
return "bcrypt"
elif h.startswith('$argon2'):
return "Argon2"
elif len(h) == 32 and all(c in '0123456789abcdef' for c in h):
return "MD5"
elif len(h) == 40:
return "SHA-1"
elif len(h) == 64:
return "SHA-256"
elif len(h) == 128:
return "SHA-512"
return "Noma'lum"
# CTF: Hash extension attack
# SHA-256(secret + message) → SHA-256(secret + message + padding + extra)
# hashpump yoki hlextend Python kutubxonasi
# hashpump -s hash -d data -a '&admin=true' -k 16
Bilimni Sinash
1. Parollarni ma'lumotlar bazasida saqlash uchun qaysi usul to'g'ri?
2. HMAC odatiy HASH dan farqi nima?
3. Salt nima uchun kerak?