3-bo‘lim
Kriptografiya asoslari
Simmetrik va asimmetrik shifrlash, xesh funksiyalar, raqamli imzo, TLS va kalitlarni boshqarish.
Ushbu bo‘lim mundarijasi
Kriptografiya - zamonaviy xavfsizlikning matematik poydevori. Uni tushunmasdan turib xavfsiz tizim qurish mumkin emas.
Uchta asosiy vosita #
Simmetrik shifrlash #
Bitta kalit - ham shifrlash, ham ochish uchun.
// 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;
}
}
$kalit = Shifrlovchi::kalitYarating();
$shifrlovchi = new Shifrlovchi($kalit);
$shifrlangan = $shifrlovchi->shifrlang('Maxfiy ma\'lumot');
echo $shifrlangan . "\n";
echo $shifrlovchi->ochiring($shifrlangan);
7xK2mQ9pL4vZ8wN3jH6sB1cF5tR0yA...
Maxfiy ma'lumot
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.
// 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).
| Simmetrik | Asimmetrik | |
|---|---|---|
| Kalitlar | Bitta | Ikkita (ochiq + maxfiy) |
| Tezlik | Juda tez | 100-1000 marta sekin |
| Kalit almashish | Muammo | Muammo yo'q |
| Katta ma'lumot | Ha | Yo'q |
| Misollar | AES, ChaCha20 | RSA, ECC, Ed25519 |
Gibrid shifrlash:
- Tasodifiy sessiya kaliti yaratiladi (simmetrik)
- Ma'lumot shu kalit bilan shifrlanadi (tez)
- Sessiya kaliti qabul qiluvchining ochiq kaliti bilan shifrlanadi
- Ikkalasi birga yuboriladi
Bu HTTPS, PGP va boshqa ko'p tizimlarda ishlatiladi.
# 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 #
$matn = 'Salom, dunyo!';
echo hash('sha256', $matn) . "\n";
echo hash('sha256', 'Salom, dunyo?') . "\n";
a8f5f167f44f4964e6c998dee827110c0e5e4b9c8e5a0f2b3d4c1e6a9b8f7d02
3c9e1a7b5d8f2046e3b7c9a1f4d6e8b2c5a7f9d1e3b6c8a0f2d4e7b9c1a3f5d8
- Bir tomonlama - xeshdan asl matnni topib bo'lmaydi
- Determinatsiyalangan - bir xil kirish, bir xil chiqish
- Ko'chki effekti - bir bit o'zgarsa, xesh butunlay boshqacha
- To'qnashuvga chidamli - ikki xil matn bir xil xesh bermaydi
- Tez - katta faylni ham tez hisoblaydi
| Algoritm | Holati |
|---|---|
| MD5 | Buzilgan - ishlatmang |
| SHA-1 | Buzilgan - ishlatmang |
| SHA-256 | Xavfsiz - umumiy maqsad uchun |
| SHA-3 | Xavfsiz - zamonaviy |
| BLAKE2, BLAKE3 | Xavfsiz va tezroq |
| bcrypt, argon2 | Faqat parollar uchun |
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:
$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 #
sha256sum ubuntu-24.04.iso
8f3a1d0e4b7c2a5f9d1e3b6c8a0f2d4e7b9c1a35d8f2046e3b7c9a1f4d6e8b2c ubuntu-24.04.iso
function faylYaxlitmi(string $yol, string $kutilganXesh): bool
{
return hash_equals($kutilganXesh, hash_file('sha256', $yol));
}
HMAC - kalit bilan xesh #
// Xabar haqiqiyligini tekshirish
$imzo = hash_hmac('sha256', $tana, $maxfiySir);
// Tekshirish
if (!hash_equals($imzo, $kelganImzo)) {
throw new NotogriImzo();
}
hash_equals majburiyif ($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 #
// 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);
bool(true)
TLS va HTTPS #
# 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
notBefore=Aug 15 08:22:31 2026 GMT
notAfter=Nov 13 08:22:30 2026 GMT
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;
}
Muddati tugagan sertifikat - saytga kirish imkonsiz bo'ladi.
# Cron da avtomatik yangilash
0 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
Va monitoring qo'shing: 14 kun qolganda ogohlantirsin.
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 #
// 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 yaramaydiuniqid() 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().
// 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 #
// 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);
}
}
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 #
| Xato | Oqibati |
|---|---|
| O'z algoritmini yozish | Deyarli har doim buzilgan |
| ECB rejimi | Naqsh ko'rinadi |
| Nonce takrorlash | Ma'lumot chiqadi |
| Zaif tasodifiy son | Token bashorat qilinadi |
| Parol uchun tez xesh | Tez ochiladi |
=== bilan imzo solishtirish | Vaqt hujumi |
| Kalit kod ichida | Git ga tushadi |
| Sertifikatni tekshirmaslik | O'rtadagi odam hujumi |
| Eskirgan algoritm (MD5, SHA-1, DES) | Buzilgan |
| Shifrlash bor, yaxlitlik yo'q | Ma'lumot o'zgartiriladi |
Kriptografiyani o'zingiz amalga oshirmang.
Yuqori darajali kutubxonalardan foydalaning:
- PHP:
libsodium(sodium_*funksiyalari) - Python:
cryptographykutubxonasi - JavaScript: Web Crypto API
- Go:
crypto/*standart paketlari
Ular xavfsiz standartlar bilan keladi va noto'g'ri ishlatishni qiyinlashtiradi.
Shifrlovchiklassini yozing va matnni shifrlab, ochib ko'ring.- Bir xil matnni ikki marta shifrlang - natija boshqacha bo'ldimi? Nima uchun?
sha256vapassword_hashtezligini o'lchab solishtiring.- HMAC bilan xabar imzolang va tekshiring.
hash_equalsva===farqini tushuntiring.- Ed25519 kalit juftligini yarating va hujjat imzolang.
- Let's Encrypt bilan sertifikat oling (test domenda).
- Nginx da TLS ni to'g'ri sozlang va SSL Labs da tekshiring.
uniqid()varandom_bytes()bilan 1000 ta token yarating - takrorlanish bormi?- 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_equalsbilan imzolarni doimiy vaqtda solishtiring.random_bytes()ishlating,rand()yokiuniqid()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.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.