10-bo‘lim

Ochiq kalitli kriptografiya

Kalitni oldindan kelishmasdan xavfsiz aloqa qurish - RSA, gibrid shifrlash va uning chegaralari.

🕑 14 daqiqa o‘qish 📄 911 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Kalit tarqatish muammosi
  2. Kalitlar jufti
  3. Ochiq kalit bilan shifrlash
  4. RSA ning jiddiy chegarasi
  5. Gibrid shifrlash
  6. To'ldirish rejimini to'g'ri tanlash
  7. RSA va elliptik egri chiziqlar
  8. Xulosa

Simmetrik shifrlashda ikkala tomon ham bir xil kalitni bilishi kerak. Savol tug'iladi: bu kalitni qanday yetkazish kerak?

Ochiq kalitli kriptografiya shu muammoni yechadi.

Kalit tarqatish muammosi #

PHP
function korsat(string $nom, string $qiymat): void
{
    printf("%-16s %s%s", $nom . ':', $qiymat, PHP_EOL);
}
PHP
// Simmetrik kalitlar: har juftlik uchun alohida kalit kerak
printf("%-14s %s%s", 'Ishtirokchi', 'Kerakli kalitlar', PHP_EOL);
echo str_repeat('-', 34), PHP_EOL;

foreach ([2, 5, 10, 100, 1000] as $n) {
    printf('%-14d %s%s', $n,
        number_format($n * ($n - 1) / 2, 0, '.', ' '), PHP_EOL);
}

echo PHP_EOL, 'Ochiq kalitli tizimda: har kishiga BITTA juft', PHP_EOL;
Natija
Ishtirokchi    Kerakli kalitlar
----------------------------------
2              1
5              10
10             45
100            4 950
1000           499 500

Ochiq kalitli tizimda: har kishiga BITTA juft
Ikki alohida muammo
MuammoSimmetrikOchiq kalitli
Kalitlar sonin(n-1)/2n ta juft
Notanish bilan aloqaImkonsizMumkin
Kalitni yetkazishXavfsiz kanal kerakOchiq kalit erkin tarqatiladi
TezlikJuda tezAncha sekin

Oxirgi qator muhim: ochiq kalitli algoritmlar simmetriklardan yuzlab marta sekin. Shuning uchun ular ma'lumotni to'g'ridan-to'g'ri shifrlash uchun ishlatilmaydi.

Kalitlar jufti #

PHP
// DIQQAT: bu kalit faqat DARSLIK UCHUN yaratilgan va ochiq e'lon qilingan.
// Uni hech qachon real tizimda ishlatmang.
const DEMO_MAXFIY = <<<'PEM'
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAMaCT68asinZp
/aYbrjiNHhKSbFXOLpXpcwlZYSejSoVuSyLchWD55wE/P7zLt+ZKB34zrpwFNPfq
ICInvr5o2VwoUQ30XsGOPP680send61FKUtiqZp7kMG1R/56TJXT+Lrt/ls5kRGi
IFfcWY0KhaQ6+88nMX7WAv40ivQnhhuFTo/hLIMrbdLYpoJOgNzC4gKAuyhLVIfg
2yVFyKy50MtfBa2gv5Jmz1s9FAW38pRQIThLd2TEqMtxtqB6kk3Z7W+lzZDrvvw0
XGCK2P58jBRx9utNABb4wyMWGYbrXZY9bkt64Gx+ioTlZl8rGQuNLM0MT1DNCosh
gEb5PGHjAgMBAAECggEAVmQ4bSV3mclnrv8gcqLesrhI2t6tt0+DfXuDQVUFr0Xp
Mom9suiVjd/D1L1+zQfuEWrK1MpxQXns0qX9FGaOSq0h2tGMd0M8uAY8733D10hZ
b5Q/WaspUM/h8u3YuvrAApd011QVh4vpJDprpBXw60DlcMoN9O0vuV2BDPdFBppf
RId6Fz4NzO63WjTbTvbocwZSTPWur1rbiLFDTc5jbhOUCiLmIyKuLh4MheQa8PFS
y6CCA8YPzLWLXOXW5cDTrOTut0cr8J9fdinm1TuxjHlgxm7tWFEQZwJHOLVHNB4I
o5qBDDD7XwBnijiLSejmAc2OiCPHUPZZY52VkvvLmQKBgQDhuRC+UOgQO/7O4wWf
3hwjsxMWydThnK10+i4EakVEOOC3DtjbC/lv4zvrVdS8w1/gX2qyeZ4F/0UAL/Sc
31C9NDkaqhIGjF/AN4NEBp5d0+dJYR2hoJDb/j4vnGBx+Fa/cFSOj443ZnJB9PMp
OoGcRXKSTIXwQdSgq7tyKngCnwKBgQDZ+Ttn9LSlT8RZZpI2FQ8oObI/3cvaTvHI
eYoviwUmBVJlwj27JNAiYqfy4VLmXcxqbn+snkpYL50qPm+/SfRXcXIm6CngSLtS
be2wf4OyAuYvAvtoJb5zhimU+uVpF3HTBi8nPGGwK93XoRDVwSRsNN17ahdmrCqJ
nBwNNbb+PQKBgQCA07r2o/6OpW88bN2c7Itq5J2UeAUD7wQgq1jwNCbsVPoMAHFM
M31dmndsTURpp6hkypB+5GKIUbTz8mrNzbarBc9BpKc9DYjoj8ZfYNep/XMXslHT
GW0T4ftj+QAii/YWtOnNo6krfVDgzAisEzQ+GHTXgs0+3pOYT+tfsVVlSQKBgQCt
HcbSr4TxbkLRhidFkMAzAG/TTYJj5iMdR3o6fD0gj0V70CNbCMfNJ3Gf8tj2YTTC
qvP30tfU5iv6qw/xavkGofE5eVYY7Wro8qm+befYb3kFiWbGtoNmGP3ZdtLQ/m/G
W7kDfm9PjedpJGDMg9M7pVjqdb4UK1S1aijVTP4DOQKBgHMmAkzUb6XG2fNPJ3oi
dmcKb6VLKhAFtUiasNeo2EtN3F2jBbs7hLbbAqJEknhyqZttmZQA/azq6BYUUFuO
JaI72NPuT7d3qxciD1IrcwLXbGYbRiHbMvMNrS//FNFgdoNgLqIy6tu8AieLa769
bIqqSM4fDts4Kt1eSpsvjKYo
-----END PRIVATE KEY-----
PEM;

const DEMO_OCHIQ = <<<'PEM'
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwDGgk+vGrIp2af2mG644
jR4SkmxVzi6V6XMJWWEno0qFbksi3IVg+ecBPz+8y7fmSgd+M66cBTT36iAiJ76+
aNlcKFEN9F7Bjjz+vNLHp3etRSlLYqmae5DBtUf+ekyV0/i67f5bOZERoiBX3FmN
CoWkOvvPJzF+1gL+NIr0J4YbhU6P4SyDK23S2KaCToDcwuICgLsoS1SH4NslRcis
udDLXwWtoL+SZs9bPRQFt/KUUCE4S3dkxKjLcbagepJN2e1vpc2Q6778NFxgitj+
fIwUcfbrTQAW+MMjFhmG612WPW5LeuBsfoqE5WZfKxkLjSzNDE9QzQqLIYBG+Txh
4wIDAQAB
-----END PUBLIC KEY-----
PEM;
PHP
$maxfiy = openssl_pkey_get_private(DEMO_MAXFIY);
$tafsilot = openssl_pkey_get_details($maxfiy);

korsat('turi', ['rsa', 'dsa', 'dh', 'ec'][$tafsilot['type']] ?? 'nomalum');
korsat('uzunlik', $tafsilot['bits'] . ' bit');
korsat('modul (n)', substr(bin2hex($tafsilot['rsa']['n']), 0, 40) . '...');
korsat('daraja (e)', bin2hex($tafsilot['rsa']['e']));

// Ochiq kalitni maxfiy kalitdan chiqarish MUMKIN
$tozala = static fn(string $pem): string => preg_replace('/\s+/', '', $pem);

korsat('mos keladimi',
    $tozala($tafsilot['key']) === $tozala(DEMO_OCHIQ) ? 'ha' : 'yoq');
Natija
turi:            rsa
uzunlik:         2048 bit
modul (n):       c031a093ebc6ac8a7669fda61bae388d1e12926c...
daraja (e):      010001
mos keladimi:    ha
Yo'nalish bir tomonlama

Ochiq kalitni maxfiy kalitdan hisoblash oson. Teskarisi - maxfiy kalitni ochiqdan chiqarish - amalda imkonsiz.

RSA da bu katta sonlarni ko'paytuvchilarga ajratish qiyinligiga asoslangan: n = p × q ni bilgan holda p va q ni topish 2048 bitda amalda imkonsiz.

Shu sababli:

KalitKim biladiQayerda saqlanadi
OchiqHammaHar joyda, erkin tarqatiladi
MaxfiyFaqat egasiHimoyalangan joyda, hech qachon uzatilmaydi

Yuqoridagi kalit darslik uchun yaratilgan va bu yerda ochiq e'lon qilingan - demak u endi maxfiy emas va hech narsani himoya qilmaydi.

Ochiq kalit bilan shifrlash #

PHP
$maxfiy = openssl_pkey_get_private(DEMO_MAXFIY);

$sir = 'Uchrashuv soat 15:00 da';

// Shifrlash - OCHIQ kalit bilan (har kim qila oladi)
$ok = openssl_public_encrypt($sir, $shifr, DEMO_OCHIQ,
    OPENSSL_PKCS1_OAEP_PADDING);

var_dump($ok);
korsat('shifr uzunligi', strlen($shifr) . ' bayt');

// Ochish - MAXFIY kalit bilan (faqat egasi)
$ok = openssl_private_decrypt($shifr, $ochiq, $maxfiy,
    OPENSSL_PKCS1_OAEP_PADDING);

var_dump($ok);
korsat('ochilgan', $ochiq);

// Ochiq kalit bilan ochib bo'lmaydi
$natija = @openssl_public_decrypt($shifr, $x, DEMO_OCHIQ,
    OPENSSL_PKCS1_OAEP_PADDING);
korsat('ochiq kalit bilan', var_export($natija, true));
Natija
bool(true)
shifr uzunligi:  256 bayt
bool(true)
ochilgan:        Uchrashuv soat 15:00 da
ochiq kalit bilan: false
Shifrmatn har safar boshqacha

Yuqoridagi kodni ikki marta ishga tushirsangiz, shifrmatn har xil chiqadi - garchi matn va kalit bir xil bo'lsa ham.

Sabab: OAEP to'ldirish ichida tasodifiy qism bor. Bu ataylab shunday: aks holda hujumchi ma'lum matnlarni shifrlab, natijalarni solishtira olardi.

Shu sababli yuqoridagi misolda shifrmatnning o'zi emas, faqat uzunligi chiqarildi.

RSA ning jiddiy chegarasi #

PHP
$maxfiy = openssl_pkey_get_private(DEMO_MAXFIY);
$kalitBayt = openssl_pkey_get_details($maxfiy)['bits'] / 8;

korsat('kalit', $kalitBayt . ' bayt');
korsat('OAEP xarajati', '42 bayt (SHA-1 bilan)');
korsat('eng koto matn', ($kalitBayt - 42) . ' bayt');

echo PHP_EOL;

foreach ([100, 200, 214, 215, 500] as $uz) {
    $matn = str_repeat('x', $uz);
    $ok = @openssl_public_encrypt($matn, $s, DEMO_OCHIQ,
        OPENSSL_PKCS1_OAEP_PADDING);
    printf('%3d bayt: %s%s', $uz, $ok ? 'shifrlandi' : 'RAD ETILDI', PHP_EOL);
}
Natija
kalit:           256 bayt
OAEP xarajati:   42 bayt (SHA-1 bilan)
eng koto matn:   214 bayt

100 bayt: shifrlandi
200 bayt: shifrlandi
214 bayt: shifrlandi
215 bayt: RAD ETILDI
500 bayt: RAD ETILDI
RSA bilan katta ma'lumotni shifrlab bo'lmaydi

2048 bitlik kalit bilan eng ko'pi bilan 214 bayt shifrlanadi. Bu bitta jumla.

Yechim - gibrid shifrlash:

QadamNima qilinadi
1Tasodifiy simmetrik kalit yaratiladi (32 bayt)
2Ma'lumot shu kalit bilan AES-GCM da shifrlanadi
3Kalit RSA bilan shifrlanadi
4Ikkalasi birga yuboriladi

Shunday qilib RSA faqat 32 baytni shifrlaydi - bu uning chegarasiga bemalol sig'adi.

Aynan shu usul TLS, PGP, S/MIME va shifrlangan pochtada ishlatiladi.

Gibrid shifrlash - ikkala usulning kuchli tomoni Yuboruvchi 1. random_bytes(32) → sessiya kaliti 2. AES-GCM(malumot, sessiya) 3. RSA(sessiya, ochiq_kalit) RSA faqat 32 baytni shifrlaydi Uzatiladi shifrlangan kalit (256 B) shifrlangan ma'lumot ikkalasi ham ochiq kanalda Qabul qiluvchi 1. RSA_och(kalit, maxfiy_kalit) 2. AES-GCM_och(malumot, sessiya) 3. ochiq matn faqat maxfiy kalit egasi ocha oladi Nima uchun shunday RSA sekin va 214 bayt bilan cheklangan - lekin kalit tarqatish muammosini yechadi. AES tez va cheksiz hajm bilan ishlaydi - lekin kalitni oldindan bilishni talab qiladi. Amalda TLS, PGP, S/MIME, shifrlangan zaxira nusxalar - hammasi aynan shu sxemadan foydalanadi.
Ochiq kalit - kalitni yetkazish uchun; simmetrik kalit - ma'lumot uchun

Gibrid shifrlash #

PHP
final class GibridKonvert
{
    public function yop(string $matn, string $ochiqKalit): array
    {
        // 1. Bir martalik sessiya kaliti
        $sessiya = random_bytes(32);
        $nonce = random_bytes(12);
        $teg = '';

        // 2. Ma'lumotni AES-GCM bilan shifrlaymiz
        $shifr = openssl_encrypt($matn, 'aes-256-gcm', $sessiya,
            OPENSSL_RAW_DATA, $nonce, $teg);

        // 3. Sessiya kalitini RSA bilan shifrlaymiz
        if (!openssl_public_encrypt($sessiya, $shifrKalit, $ochiqKalit,
                OPENSSL_PKCS1_OAEP_PADDING)) {
            throw new RuntimeException('kalitni shifrlab bolmadi');
        }

        return [
            'kalit' => base64_encode($shifrKalit),
            'nonce' => base64_encode($nonce),
            'teg' => base64_encode($teg),
            'malumot' => base64_encode($shifr),
        ];
    }

    public function och(array $paket, string $maxfiyKalit): string
    {
        $maxfiy = openssl_pkey_get_private($maxfiyKalit);
        if ($maxfiy === false) {
            throw new RuntimeException('maxfiy kalit oqilmadi');
        }

        // 1. Sessiya kalitini ochamiz
        if (!openssl_private_decrypt(base64_decode($paket['kalit']),
                $sessiya, $maxfiy, OPENSSL_PKCS1_OAEP_PADDING)) {
            throw new RuntimeException('sessiya kaliti ochilmadi');
        }

        // 2. Ma'lumotni ochamiz
        $matn = openssl_decrypt(base64_decode($paket['malumot']),
            'aes-256-gcm', $sessiya, OPENSSL_RAW_DATA,
            base64_decode($paket['nonce']), base64_decode($paket['teg']));

        if ($matn === false) {
            throw new RuntimeException('butunlik tekshiruvi otmadi');
        }

        return $matn;
    }
}
PHP
$gibrid = new GibridKonvert();

// Katta ma'lumot - RSA yolg'iz uddalay olmaydi
$katta = str_repeat('Maxfiy hisobot qatori. ', 500);
echo 'malumot hajmi: ', strlen($katta), ' bayt', PHP_EOL;

$paket = $gibrid->yop($katta, DEMO_OCHIQ);

foreach ($paket as $nom => $qiymat) {
    printf('%-9s %d belgi%s', $nom . ':', strlen($qiymat), PHP_EOL);
}

$ochilgan = $gibrid->och($paket, DEMO_MAXFIY);
echo PHP_EOL, 'ochildi va mos keldi: ',
    $ochilgan === $katta ? 'ha' : 'yoq', PHP_EOL;
Natija
malumot hajmi: 11500 bayt
kalit:    344 belgi
nonce:    16 belgi
teg:      24 belgi
malumot:  15336 belgi

ochildi va mos keldi: ha

Buzilgan paket rad etiladi:

PHP
$gibrid = new GibridKonvert();
$paket = $gibrid->yop('Maxfiy xabar', DEMO_OCHIQ);

$sinovlar = [
    'malumot buzildi' => static function () use ($gibrid, $paket) {
        $p = $paket;
        $x = base64_decode($p['malumot']);
        $x[0] = chr(ord($x[0]) ^ 0xff);
        $p['malumot'] = base64_encode($x);
        return $gibrid->och($p, DEMO_MAXFIY);
    },
    'teg buzildi' => static function () use ($gibrid, $paket) {
        $p = $paket;
        $x = base64_decode($p['teg']);
        $x[0] = chr(ord($x[0]) ^ 0xff);
        $p['teg'] = base64_encode($x);
        return $gibrid->och($p, DEMO_MAXFIY);
    },
    'kalit buzildi' => static function () use ($gibrid, $paket) {
        $p = $paket;
        $x = base64_decode($p['kalit']);
        $x[0] = chr(ord($x[0]) ^ 0xff);
        $p['kalit'] = base64_encode($x);
        return $gibrid->och($p, DEMO_MAXFIY);
    },
];

foreach ($sinovlar as $nom => $sinov) {
    try {
        $sinov();
        printf('%-18s OTDI - KUTILMAGAN%s', $nom, PHP_EOL);
    } catch (RuntimeException $x) {
        printf('%-18s RAD: %s%s', $nom, $x->getMessage(), PHP_EOL);
    }
}
Natija
malumot buzildi    RAD: butunlik tekshiruvi otmadi
teg buzildi        RAD: butunlik tekshiruvi otmadi
kalit buzildi      RAD: sessiya kaliti ochilmadi

To'ldirish rejimini to'g'ri tanlash #

PHP
$sir = 'test';

// OAEP - to'g'ri tanlov
$ok1 = openssl_public_encrypt($sir, $s1, DEMO_OCHIQ,
    OPENSSL_PKCS1_OAEP_PADDING);

// PKCS#1 v1.5 - eskirgan
$ok2 = openssl_public_encrypt($sir, $s2, DEMO_OCHIQ,
    OPENSSL_PKCS1_PADDING);

// To'ldirishsiz - juda xavfli
$ok3 = @openssl_public_encrypt(str_pad($sir, 256, "\x00", STR_PAD_LEFT),
    $s3, DEMO_OCHIQ, OPENSSL_NO_PADDING);

printf("%-22s %s%s", 'OAEP:', $ok1 ? 'ishladi' : 'xato', PHP_EOL);
printf("%-22s %s%s", 'PKCS#1 v1.5:', $ok2 ? 'ishladi' : 'xato', PHP_EOL);
printf("%-22s %s%s", 'toldirishsiz:', $ok3 ? 'ishladi' : 'xato', PHP_EOL);
Natija
OAEP:                  ishladi
PKCS#1 v1.5:           ishladi
toldirishsiz:          ishladi
Faqat OAEP ishlating
To'ldirishHolati
OAEP (OPENSSL_PKCS1_OAEP_PADDING)To'g'ri tanlov
PKCS#1 v1.5 (OPENSSL_PKCS1_PADDING)Eskirgan, Bleichenbacher hujumiga ochiq
To'ldirishsiz (OPENSSL_NO_PADDING)Halokatli

PKCS#1 v1.5 to'ldirishga qarshi 1998-yilda Bleichenbacher hujumi e'lon qilingan: server "to'ldirish noto'g'ri" degan xatoni ajratib ko'rsatsa, hujumchi shifrni bosqichma-bosqich ochishi mumkin.

Bu hujum yillar davomida qayta-qayta paydo bo'lgan (ROBOT, 2017). Sabab - eski protokollar bilan moslikni saqlash.

To'ldirishsiz RSA esa deterministik: bir xil matn har doim bir xil shifr beradi, va matematik xususiyatlari saqlanadi (E(a) × E(b) = E(a×b)). Bu hujumchiga ochiq imkoniyat.

RSA va elliptik egri chiziqlar #

PHP
// Bir xil xavfsizlik darajasi uchun kerakli kalit uzunligi
$jadval = [
    ['80 bit', '1024', '160', 'eskirgan'],
    ['112 bit', '2048', '224', 'minimal'],
    ['128 bit', '3072', '256', 'tavsiya etiladi'],
    ['192 bit', '7680', '384', 'yuqori'],
    ['256 bit', '15360', '521', 'juda yuqori'],
];

printf("%-10s %-10s %-8s %s%s", 'Xavfsizlik', 'RSA bit', 'EC bit',
    'Baho', PHP_EOL);
echo str_repeat('-', 48), PHP_EOL;
foreach ($jadval as $q) {
    printf("%-10s %-10s %-8s %s%s", ...[...$q, PHP_EOL]);
}
Natija
Xavfsizlik RSA bit    EC bit   Baho
------------------------------------------------
80 bit     1024       160      eskirgan
112 bit    2048       224      minimal
128 bit    3072       256      tavsiya etiladi
192 bit    7680       384      yuqori
256 bit    15360      521      juda yuqori
Nima uchun EC afzal

128 bitlik xavfsizlik uchun RSA da 3072 bit, elliptik egri chiziqlarda esa atigi 256 bit kerak.

JihatRSA-3072EC P-256
Kalit hajmi384 bayt32 bayt
Imzo hajmi384 bayt~64-72 bayt
Imzolash tezligiSekinTez
Tekshirish tezligiTezO'rtacha
Yangi tizimlar uchunHa, lekinAfzal

Yangi loyihada:

VazifaTanlov
ImzoEd25519 yoki ECDSA P-256
Kalit almashinuviX25519 yoki ECDH P-256
Shifrlash (gibrid)ECIES yoki RSA-OAEP
Eski tizim bilan moslikRSA-2048 dan kam emas

PHP ning openssl kengaytmasi Ed25519 ni to'liq qo'llab- quvvatlamaydi; u uchun sodium kengaytmasi kerak.

Amaliy topshiriq
  1. 10, 100 va 1000 ishtirokchi uchun simmetrik kalitlar sonini hisoblang.
  2. Kalit juftini o'z mashinangizda yarating (openssl genpkey).
  3. Ochiq kalit bilan qisqa matnni shifrlang va maxfiy kalit bilan oching.
  4. Ochiq kalit bilan ochishga urinib ko'ring.
  5. Turli uzunlikdagi matnlarni shifrlab, chegarani toping.
  6. Nima uchun bu chegara mavjudligini tushuntiring.
  7. Gibrid shifrlash sinfini yozing.
  8. Uch xil buzilgan paketni sinang - hammasi rad etildimi?
  9. OAEP va PKCS#1 v1.5 farqini yozing.
  10. RSA-3072 va EC P-256 kalit hajmlarini solishtiring.

Xulosa #

  • Simmetrik shifrlashda n ishtirokchi uchun n(n-1)/2 kalit kerak.
  • Ochiq kalitli kriptografiyada har kishiga bitta juft yetarli.
  • Ochiq kalit erkin tarqatiladi, maxfiy kalit hech qachon uzatilmaydi.
  • Ochiq kalitni maxfiydan chiqarish oson; teskarisi amalda imkonsiz.
  • RSA bilan 2048 bitlik kalitda faqat 214 baytgacha shifrlash mumkin.
  • Shuning uchun gibrid shifrlash ishlatiladi: ma'lumot AES bilan, kalit RSA bilan.
  • TLS, PGP va S/MIME - hammasi shu sxemaga asoslangan.
  • OAEP to'ldirishida tasodifiylik bor - shifrmatn har safar boshqacha.
  • Faqat OAEP ishlating; PKCS#1 v1.5 Bleichenbacher hujumiga ochiq.
  • Bir xil xavfsizlik uchun EC kalitlari RSA dan o'n barobar qisqa.

Keyingi bo'limda raqamli imzolar bilan tanishamiz.

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.