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.

MD5 / SHA-1 / SHA-256 bcrypt / scrypt / Argon2 Rainbow Table HMAC CTF Hash Cracking

1 Hash Funksiya Nima?

Hash Funksiya: H(input) = digest Kirish (ixtiyoriy o'lcham) "hello" "hello world" (11 B) 1GB video fayl H(x) SHA-256, MD5... Chiqish (qat'iy o'lcham) SHA-256("hello"): 2cf24dba5fb0...b854521ee SHA-256("Hello"): 185f8db32921...b05a88580 ← Bitta harf farq → butunlay boshqa! Bir tomonlama • Deterministik • Tez • Avalanche effekti

Kriptografik Hash Xususiyatlari

1

Pre-image Resistance (Bir tomonlama)

H(x) = h berilsa, x topish hisoblash jihatdan imkonsiz

2

Second Pre-image Resistance

x berilsa, H(x')=H(x) bo'lgan x'≠x topish imkonsiz

3

Collision Resistance

H(x)=H(y) bo'lgan x≠y juftini topish imkonsiz

4

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

Hash Algoritmlar Xavfsizlik Darajasi MD5 128-bit • BUZILGAN SHA-1 160-bit • ZAIF SHA-256 256-bit • XAVFSIZ SHA-3-256 256-bit • XAVFSIZ Qizil = Buzilgan, To'q sariq = Zaif, Yashil/Ko'k = Xavfsiz
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.

MD5
~60 milliard/soniya
(GPU, RTX 3090)
SHA-256
~10 milliard/soniya
Ham juda tez
bcrypt (cost=12)
~10 ta/soniya
Maqsad shu!
Parol Hashlash: To'g'ri yo'l (Salt + KDF) RO'YXATDAN O'TISH Parol: "mypassword" Salt (tasodifiy): "x7k9..." → bcrypt("mypass", salt) Ma'lumotlar omboriga saqlanadi: $2b$12$x7k9...hashed_output LOGIN TEKSHIRISH Kirish: "mypassword" DB dan: "$2b$12$x7k9..." → bcrypt.verify(pass, hash) ✓ Mos → Kirish ruxsat Xavfsizlik Sabablari ✓ Salt → bir xil parol → har xil hash ✓ Sekin → brute force qimmat ✓ Adaptive → cost factor oshirish ✓ Bir tomonlama → teskari yo'q ✓ Har foydalanuvchi → alohida salt → Rainbow table ishlamaydi! bcrypt formati: $2b$ + cost + $ + 22-char salt + 31-char hash

Parol KDF (Key Derivation Function) Taqqoslash

bcrypt Tavsiya

Cost factor (work factor) — 2^cost ta iteratsiya. 1999-yil, hali xavfsiz. Xotira: 4 KB.

scrypt Tavsiya

CPU + Xotira intensiv. N (CPU), r (xotira), p (parallel) parametrlar. GPU bilan hujumga chidamli.

Argon2id Eng Yaxshi

Password Hashing Competition g'olibi (2015). Side-channel + GPU hujumlariga chidamli. OWASP tavsiyasi.

PBKDF2 Qabul qilinarli

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
password5f4dcc3b5aa7...
123456e10adc3949ba...
qwertyd8578edf8458...
admin21232f297a57...

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?