3-bo‘lim

Kriptografiya asoslari

Simmetrik va asimmetrik shifrlash, xesh funksiyalar, raqamli imzo, TLS va kalitlarni boshqarish.

🕑 17 daqiqa o‘qish 📄 1 175 so‘z 👁 6 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Uchta asosiy vosita
  2. Simmetrik shifrlash
  3. Asimmetrik shifrlash
  4. Xesh funksiyalar
  5. Fayl yaxlitligini tekshirish
  6. HMAC - kalit bilan xesh
  7. Raqamli imzo
  8. TLS va HTTPS
  9. Tasodifiy sonlar
  10. Kalitlarni boshqarish
  11. Umumiy xatolar
  12. Xulosa

Kriptografiya - zamonaviy xavfsizlikning matematik poydevori. Uni tushunmasdan turib xavfsiz tizim qurish mumkin emas.

Uchta asosiy vosita #

Uch asosiy vosita va ular hal qiladigan muammo Shifrlash Maxfiylik "Faqat men o'qiy olaman" • AES (simmetrik) • RSA, ECC (asimmetrik) • Qaytariladigan • Kalit kerak Xesh Yaxlitlik "O'zgartirilmaganini bilaman" • SHA-256, SHA-3 • bcrypt (parollar uchun) • Qaytarilmaydigan • Kalit kerak emas Raqamli imzo Haqiqiylik "Kim yuborganini bilaman" • RSA, ECDSA, Ed25519 • Xesh + maxfiy kalit • Inkor qila olmaslik • Ochiq kalit bilan tekshirish
Har biri boshqa muammoni hal qiladi

Simmetrik shifrlash #

Bitta kalit - ham shifrlash, ham ochish uchun.

Simmetrik shifrlash Ochiq matn "Salom" AES shifrlash Shifr matn 8fA3kL9x... AES ochish BITTA MAXFIY KALIT
Tez, lekin kalitni xavfsiz uzatish muammosi bor
PHP
// libsodium - zamonaviy va xavfsiz
final class Shifrlovchi
{
    public function __construct(private string $kalit)
    {
        if (strlen($kalit) !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
            throw new InvalidArgumentException('Kalit 32 bayt bo\'lishi kerak');
        }
    }

    public static function kalitYarating(): string
    {
        return sodium_crypto_secretbox_keygen();
    }

    public function shifrlang(string $matn): string
    {
        $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
        $shifr = sodium_crypto_secretbox($matn, $nonce, $this->kalit);

        return base64_encode($nonce . $shifr);
    }

    public function ochiring(string $shifrlangan): string
    {
        $malumot = base64_decode($shifrlangan, true)
            ?: throw new ShifrlashXatosi('Noto\'g\'ri format');

        if (strlen($malumot) < SODIUM_CRYPTO_SECRETBOX_NONCEBYTES) {
            throw new ShifrlashXatosi('Ma\'lumot juda qisqa');
        }

        $nonce = substr($malumot, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
        $shifr = substr($malumot, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

        $natija = sodium_crypto_secretbox_open($shifr, $nonce, $this->kalit);

        if ($natija === false) {
            throw new ShifrlashXatosi('Ochib bo\'lmadi - kalit yoki ma\'lumot noto\'g\'ri');
        }

        return $natija;
    }
}
PHP
$kalit = Shifrlovchi::kalitYarating();
$shifrlovchi = new Shifrlovchi($kalit);

$shifrlangan = $shifrlovchi->shifrlang('Maxfiy ma\'lumot');
echo $shifrlangan . "\n";
echo $shifrlovchi->ochiring($shifrlangan);
Natija
7xK2mQ9pL4vZ8wN3jH6sB1cF5tR0yA...
Maxfiy ma'lumot
Nonce ni takrorlamang

Nonce (number used once) har bir shifrlash uchun yangi bo'lishi kerak.

Bir xil kalit va bir xil nonce bilan ikki xabar shifrlansa, hujumchi ularni solishtirib ma'lumot chiqarishi mumkin.

random_bytes() har safar yangi nonce beradi - uni saqlang (u maxfiy emas) va shifr matn bilan birga uzating.

ECB rejimini ishlatmang
PHP
// XAVFLI
openssl_encrypt($matn, 'aes-256-ecb', $kalit);

ECB rejimida bir xil bloklar bir xil shifrlanadi - natijada rasm shifrlanganda ham naqsh ko'rinib turadi.

To'g'ri rejimlar: GCM, ChaCha20-Poly1305 - ular yaxlitlikni ham tekshiradi (autentifikatsiyalangan shifrlash).

Asimmetrik shifrlash #

Ikki kalit: ochiq (hamma biladi) va maxfiy (faqat egasi).

Ochiq kalit bilan shifrlash Husanboy xabar yubormoqchi Jasurning OCHIQ kaliti hamma biladi Shifrlangan 4kL8mQ... Jasur o'qiy oladi Jasurning MAXFIY kaliti Ochiq kalit bilan shifrlangan xabarni faqat maxfiy kalit ocha oladi Kalitni oldindan kelishish shart emas - bu asosiy afzallik
Sekin, lekin kalit almashish muammosini hal qiladi
SimmetrikAsimmetrik
KalitlarBittaIkkita (ochiq + maxfiy)
TezlikJuda tez100-1000 marta sekin
Kalit almashishMuammoMuammo yo'q
Katta ma'lumotHaYo'q
MisollarAES, ChaCha20RSA, ECC, Ed25519
Amalda ikkalasi birga ishlatiladi

Gibrid shifrlash:

  1. Tasodifiy sessiya kaliti yaratiladi (simmetrik)
  2. Ma'lumot shu kalit bilan shifrlanadi (tez)
  3. Sessiya kaliti qabul qiluvchining ochiq kaliti bilan shifrlanadi
  4. Ikkalasi birga yuboriladi

Bu HTTPS, PGP va boshqa ko'p tizimlarda ishlatiladi.

Terminal
# Kalit juftligini yaratish
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out maxfiy.pem
openssl rsa -pubout -in maxfiy.pem -out ochiq.pem

# Ed25519 - zamonaviy va tezroq
ssh-keygen -t ed25519 -C "[email protected]"

Xesh funksiyalar #

PHP
$matn = 'Salom, dunyo!';

echo hash('sha256', $matn) . "\n";
echo hash('sha256', 'Salom, dunyo?') . "\n";
Natija
a8f5f167f44f4964e6c998dee827110c0e5e4b9c8e5a0f2b3d4c1e6a9b8f7d02
3c9e1a7b5d8f2046e3b7c9a1f4d6e8b2c5a7f9d1e3b6c8a0f2d4e7b9c1a3f5d8
Xesh xususiyatlari
  1. Bir tomonlama - xeshdan asl matnni topib bo'lmaydi
  2. Determinatsiyalangan - bir xil kirish, bir xil chiqish
  3. Ko'chki effekti - bir bit o'zgarsa, xesh butunlay boshqacha
  4. To'qnashuvga chidamli - ikki xil matn bir xil xesh bermaydi
  5. Tez - katta faylni ham tez hisoblaydi
AlgoritmHolati
MD5Buzilgan - ishlatmang
SHA-1Buzilgan - ishlatmang
SHA-256Xavfsiz - umumiy maqsad uchun
SHA-3Xavfsiz - zamonaviy
BLAKE2, BLAKE3Xavfsiz va tezroq
bcrypt, argon2Faqat parollar uchun
Parol uchun SHA-256 yaramaydi

SHA-256 tez - bu fayl yaxlitligi uchun yaxshi, parol uchun yomon.

Zamonaviy videokarta soniyasiga milliardlab SHA-256 hisoblaydi. 8 belgili parol bir necha soatda ochiladi.

Parol uchun ataylab sekin algoritm kerak:

PHP
$xesh = password_hash($parol, PASSWORD_ARGON2ID, [
    'memory_cost' => 65536,   // 64 MB
    'time_cost'   => 4,
    'threads'     => 2,
]);

Argon2 xotira ham talab qiladi - bu videokartada parallel hisoblashni qiyinlashtiradi.

Fayl yaxlitligini tekshirish #

Terminal
sha256sum ubuntu-24.04.iso
Natija
8f3a1d0e4b7c2a5f9d1e3b6c8a0f2d4e7b9c1a35d8f2046e3b7c9a1f4d6e8b2c  ubuntu-24.04.iso
PHP
function faylYaxlitmi(string $yol, string $kutilganXesh): bool
{
    return hash_equals($kutilganXesh, hash_file('sha256', $yol));
}

HMAC - kalit bilan xesh #

PHP
// Xabar haqiqiyligini tekshirish
$imzo = hash_hmac('sha256', $tana, $maxfiySir);

// Tekshirish
if (!hash_equals($imzo, $kelganImzo)) {
    throw new NotogriImzo();
}
hash_equals majburiy
PHP
if ($imzo === $kelganImzo) { }        // vaqt hujumiga ochiq
if (hash_equals($imzo, $kelganImzo)) { }   // doimiy vaqtda

Oddiy === birinchi farqli baytda to'xtaydi. Hujumchi javob vaqtini o'lchab imzoni belgi-belgi topishi mumkin.

Raqamli imzo #

Raqamli imzo - shifrlashning teskarisi Imzolash Hujjat Xesh MAXFIY kalit bilan Hujjat + Imzo yuboriladi Tekshirish Hujjat Xesh Imzo OCHIQ kalit bilan Mos keldimi? Imzo uchta narsani isbotlaydi 1. Kim yozgan · 2. Hujjat o'zgarmagan · 3. Muallif inkor qila olmaydi
Shifrlashda ochiq kalit bilan shifrlanadi, imzolashda - maxfiy kalit bilan
PHP
// Ed25519 - zamonaviy imzo
$juftlik = sodium_crypto_sign_keypair();
$maxfiy  = sodium_crypto_sign_secretkey($juftlik);
$ochiq   = sodium_crypto_sign_publickey($juftlik);

$xabar = 'Buyurtma #1042 tasdiqlandi';
$imzo = sodium_crypto_sign_detached($xabar, $maxfiy);

// Tekshirish (faqat ochiq kalit kerak)
$togrimi = sodium_crypto_sign_verify_detached($imzo, $xabar, $ochiq);

var_dump($togrimi);
Natija
bool(true)

TLS va HTTPS #

TLS qo'l berish (soddalashtirilgan) Brauzer Server 1. Salom + qo'llab-quvvatlanadigan algoritmlar 2. Sertifikat + tanlangan algoritm 3. Sertifikatni tekshirish 4. Sessiya kaliti (ochiq kalit bilan shifrlangan) 5. Simmetrik shifrlangan ma'lumot almashinuvi Asimmetrik - faqat kalit almashish uchun, keyin tezroq simmetrik ishlatiladi
TLS 1.3 bu jarayonni bir marta murojaat bilan bajaradi
Terminal
# Let's Encrypt bilan bepul sertifikat
sudo certbot --nginx -d dokon.uz -d www.dokon.uz

# Sertifikatni tekshirish
openssl s_client -connect dokon.uz:443 -servername dokon.uz < /dev/null 2>/dev/null | openssl x509 -noout -dates
Natija
notBefore=Aug 15 08:22:31 2026 GMT
notAfter=Nov 13 08:22:30 2026 GMT
NGINX
server {
    listen 443 ssl http2;
    server_name dokon.uz;

    ssl_certificate     /etc/letsencrypt/live/dokon.uz/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dokon.uz/privkey.pem;

    # Faqat zamonaviy protokollar
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

# HTTP dan HTTPS ga yo'naltirish
server {
    listen 80;
    server_name dokon.uz www.dokon.uz;
    return 301 https://$host$request_uri;
}
Sertifikat muddatini kuzating

Muddati tugagan sertifikat - saytga kirish imkonsiz bo'ladi.

Terminal
# Cron da avtomatik yangilash
0 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

Va monitoring qo'shing: 14 kun qolganda ogohlantirsin.

O'z-o'zini imzolagan sertifikat

Ishlab chiqarishda hech qachon ishlatmang.

Foydalanuvchilar brauzer ogohlantirishini o'tkazib yuborishga o'rganib qoladi - keyin haqiqiy hujumni ham sezmaydi.

Let's Encrypt bepul va avtomatik.

Tasodifiy sonlar #

PHP
// XAVFLI - bashorat qilish mumkin
$token = rand();
$token = mt_rand();
$token = uniqid();

// XAVFSIZ - kriptografik jihatdan xavfsiz
$token = bin2hex(random_bytes(32));
$son   = random_int(100000, 999999);
uniqid() va rand() - xavfsizlik uchun yaramaydi

uniqid() vaqtga asoslangan - uni bashorat qilish mumkin.

Parolni tiklash tokeni uniqid() bilan yaratilgan bo'lsa, hujumchi taxminan qachon so'rov yuborilganini bilib, tokenni topishi mumkin.

Har doim random_bytes() yoki random_int().

PHP
// Xavfsiz token yaratish
final class TokenYaratuvchi
{
    public static function yarating(int $baytlar = 32): string
    {
        return bin2hex(random_bytes($baytlar));
    }

    public static function tasdiqlashKodi(): string
    {
        return str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);
    }
}

Kalitlarni boshqarish #

Kalitni qayerda saqlash kerak? Hech qachon • Kod ichida (Git ga tushadi) • Ma'lumotlar bazasida (shifrlangan ma'lumot bilan birga) • Jurnal fayllarida To'g'ri usullar • Muhit o'zgaruvchisi (kichik loyiha) • Vault, AWS KMS, Azure Key Vault • HSM (eng yuqori daraja) Kalit hayotiy tsikli Yaratish → Saqlash → Ishlatish → Almashtirish → Yo'q qilish Kalitlar muntazam almashtirilishi kerak (rotatsiya)
Shifrlash kaliti shifrlangan ma'lumot bilan bir joyda turmasin
PHP
// Kalit versiyalash - rotatsiya uchun
final class KalitBoshqaruvchi
{
    /** @var array<int, string> */
    private array $kalitlar;
    private int $joriyVersiya;

    public function shifrlang(string $matn): string
    {
        $shifr = $this->shifrlovchi($this->joriyVersiya)->shifrlang($matn);

        // Versiyani prefiks sifatida saqlaymiz
        return "v{$this->joriyVersiya}:{$shifr}";
    }

    public function ochiring(string $shifrlangan): string
    {
        [$versiyaQismi, $shifr] = explode(':', $shifrlangan, 2);
        $versiya = (int) ltrim($versiyaQismi, 'v');

        return $this->shifrlovchi($versiya)->ochiring($shifr);
    }
}
Nima uchun versiyalash?

Kalit almashtirilganda eski ma'lumot hali eski kalit bilan shifrlangan.

Versiya prefiksi bilan tizim qaysi kalit kerakligini biladi va ma'lumotni asta-sekin yangi kalitga ko'chirish mumkin.

Umumiy xatolar #

Kriptografiyada eng ko'p uchraydigan xatolar
XatoOqibati
O'z algoritmini yozishDeyarli har doim buzilgan
ECB rejimiNaqsh ko'rinadi
Nonce takrorlashMa'lumot chiqadi
Zaif tasodifiy sonToken bashorat qilinadi
Parol uchun tez xeshTez ochiladi
=== bilan imzo solishtirishVaqt hujumi
Kalit kod ichidaGit ga tushadi
Sertifikatni tekshirmaslikO'rtadagi odam hujumi
Eskirgan algoritm (MD5, SHA-1, DES)Buzilgan
Shifrlash bor, yaxlitlik yo'qMa'lumot o'zgartiriladi
Oltin qoida

Kriptografiyani o'zingiz amalga oshirmang.

Yuqori darajali kutubxonalardan foydalaning:

  • PHP: libsodium (sodium_* funksiyalari)
  • Python: cryptography kutubxonasi
  • JavaScript: Web Crypto API
  • Go: crypto/* standart paketlari

Ular xavfsiz standartlar bilan keladi va noto'g'ri ishlatishni qiyinlashtiradi.

Amaliy topshiriq
  1. Shifrlovchi klassini yozing va matnni shifrlab, ochib ko'ring.
  2. Bir xil matnni ikki marta shifrlang - natija boshqacha bo'ldimi? Nima uchun?
  3. sha256 va password_hash tezligini o'lchab solishtiring.
  4. HMAC bilan xabar imzolang va tekshiring.
  5. hash_equals va === farqini tushuntiring.
  6. Ed25519 kalit juftligini yarating va hujjat imzolang.
  7. Let's Encrypt bilan sertifikat oling (test domenda).
  8. Nginx da TLS ni to'g'ri sozlang va SSL Labs da tekshiring.
  9. uniqid() va random_bytes() bilan 1000 ta token yarating - takrorlanish bormi?
  10. Kalit versiyalash tizimini yozing.

Xulosa #

  • Uch vosita: shifrlash (maxfiylik), xesh (yaxlitlik), imzo (haqiqiylik).
  • Simmetrik tez, lekin kalit almashish muammosi bor.
  • Asimmetrik sekin, lekin kalitni oldindan kelishish shart emas.
  • Amalda gibrid yondashuv: asimmetrik bilan kalit almashiladi, simmetrik bilan ma'lumot shifrlanadi.
  • Nonce har safar yangi bo'lsin, ECB rejimini ishlatmang.
  • MD5 va SHA-1 buzilgan; parol uchun bcrypt yoki argon2.
  • hash_equals bilan imzolarni doimiy vaqtda solishtiring.
  • random_bytes() ishlating, rand() yoki uniqid() emas.
  • TLS asimmetrik shifrlashni faqat kalit almashish uchun ishlatadi.
  • Kalit shifrlangan ma'lumot bilan bir joyda turmasin.
  • Kriptografiyani o'zingiz amalga oshirmang - kutubxona ishlating.

Keyingi bo'limda autentifikatsiya va parollarni ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.