13-bo‘lim

Sertifikatlar va PKI

Ochiq kalit kimga tegishli ekanini isbotlash - X.509, ishonch zanjiri va tekshiruvda nima buziladi.

🕑 18 daqiqa o‘qish 📄 1 125 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Sertifikat nima
  2. Sinov muhitida o'z markazimizni quramiz
  3. Sertifikat ichida nima bor
  4. Tekshirish
  5. Endi tekshiruvni buzamiz
  6. Oraliq sertifikat va to'liq zanjir
  7. Zanjirni ko'rish
  8. Sertifikatni bekor qilish
  9. Sertifikatni PHP da tekshirish
  10. Xulosa

12-bo'lim savol bilan tugadi: ochiq kalit haqiqatan kimniki?

Javob - sertifikat: ochiq kalit va shaxsni bog'lab, uchinchi ishonchli tomon tomonidan imzolangan hujjat.

Sertifikat nima #

ElementNima yozilgan
SubjectKimga tegishli (domen, tashkilot)
IssuerKim imzolagan (sertifikat markazi)
Ochiq kalitEgasining kaliti
Amal muddatiQachondan qachongacha
SANQaysi domenlar uchun amal qiladi
KengaytmalarNima uchun ishlatilishi mumkin
ImzoYuqoridagilarning hammasi ustidan

Oxirgi qator hal qiluvchi: sertifikat - bu imzolangan ma'lumot. 11-bo'limdagi manifest bilan bir xil g'oya.

Sinov muhitida o'z markazimizni quramiz #

Bu faqat o'quv muhiti

Quyidagi buyruqlar o'zingizning mashinangizda ishlaydigan, hech kimga ta'sir qilmaydigan sinov sertifikat markazini yaratadi.

Bunday markaz internetdagi hech qanday brauzer tomonidan tan olinmaydi va olinmasligi ham kerak.

Real sayt uchun sertifikatni Let's Encrypt kabi tan olingan markazdan oling.

Terminal
export LC_ALL=C TZ=UTC

# 1. Sertifikat markazining kaliti va o'zi-imzolangan sertifikati
openssl ecparam -name prime256v1 -genkey -noout -out ca.key 2>/dev/null
openssl req -x509 -new -key ca.key -sha256 -days 3650 \
  -subj "/C=UZ/O=Namuna Lab CA/CN=Namuna Ildiz CA" -out ca.crt 2>/dev/null

# 2. Server kaliti va sertifikat so'rovi (CSR)
openssl ecparam -name prime256v1 -genkey -noout -out srv.key 2>/dev/null
openssl req -new -key srv.key \
  -subj "/C=UZ/O=Namuna/CN=xizmat.namuna.uz" -out srv.csr 2>/dev/null

# 3. Kengaytmalar - qaysi domenlar va qanday maqsad uchun
cat > srv.ext <<'EXT'
subjectAltName=DNS:xizmat.namuna.uz,DNS:www.xizmat.namuna.uz
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
EXT

# 4. Markaz so'rovni imzolaydi
openssl x509 -req -in srv.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 90 -sha256 -extfile srv.ext -out srv.crt 2>/dev/null
Terminal
openssl x509 -in srv.crt -noout -subject -issuer
Natija
subject=C=UZ, O=Namuna, CN=xizmat.namuna.uz
issuer=C=UZ, O=Namuna Lab CA, CN=Namuna Ildiz CA
Uchta fayl - uchta rol
FaylNimaMaxfiymi
srv.keyServerning maxfiy kalitiHa, hech qachon uzatilmaydi
srv.csrSo'rov: ochiq kalit + kerakli nomYo'q
srv.crtImzolangan sertifikatYo'q, har kimga beriladi

CSR (Certificate Signing Request) ichida maxfiy kalit yo'q - faqat ochiq kalit va so'ralayotgan nom. Shuning uchun uni bemalol sertifikat markaziga yuborish mumkin.

Bu muhim: maxfiy kalit hech qachon serveringizdan chiqmaydi.

Sertifikat ichida nima bor #

Terminal
openssl x509 -in srv.crt -noout -ext subjectAltName
openssl x509 -in srv.crt -noout -ext keyUsage
openssl x509 -in srv.crt -noout -ext extendedKeyUsage
openssl x509 -in srv.crt -noout -ext basicConstraints
Natija
X509v3 Subject Alternative Name: 
    DNS:xizmat.namuna.uz, DNS:www.xizmat.namuna.uz
X509v3 Key Usage: critical
    Digital Signature, Key Encipherment
X509v3 Extended Key Usage: 
    TLS Web Server Authentication
X509v3 Basic Constraints: critical
    CA:FALSE
SAN - haqiqiy domen ro'yxati

Uzoq vaqt domen CN (Common Name) maydonida yozilardi. Hozir esa u e'tiborga olinmaydi.

Barcha zamonaviy brauzerlar va kutubxonalar faqat subjectAltName (SAN) ni tekshiradi.

MaydonHolati
CNEskirgan, faqat ko'rgazma uchun
subjectAltNameYagona ishonchli manba

Agar sertifikatda SAN bo'lmasa, u zamonaviy brauzerda ishlamaydi - CN da to'g'ri domen yozilgan bo'lsa ham.

basicConstraints=CA:FALSE ham muhim: u bu sertifikat boshqa sertifikatlarni imzolay olmasligini bildiradi. Bu bo'lmasa, server sertifikati bilan soxta sertifikat yasash mumkin bo'lardi.

Tekshirish #

Terminal
# 1. Zanjir to'g'rimi
openssl verify -CAfile ca.crt srv.crt

# 2. Domen mos keladimi
openssl verify -CAfile ca.crt -verify_hostname xizmat.namuna.uz srv.crt

# 3. Muddati o'tmaganmi
openssl x509 -in srv.crt -noout -checkend 0 >/dev/null \
  && echo "srv.crt: muddati amal qiladi" \
  || echo "srv.crt: muddati otgan"
Natija
srv.crt: OK
srv.crt: OK
srv.crt: muddati amal qiladi

Endi tekshiruvni buzamiz #

Terminal
# 1. Boshqa domen so'raymiz
openssl verify -CAfile ca.crt -verify_hostname boshqa.namuna.uz srv.crt 2>&1
Natija
C=UZ, O=Namuna, CN=xizmat.namuna.uz
error 62 at 0 depth lookup: hostname mismatch
error srv.crt: verification failed
Terminal
# 2. Begona markazga ishonamiz
openssl ecparam -name prime256v1 -genkey -noout -out ca2.key 2>/dev/null
openssl req -x509 -new -key ca2.key -sha256 -days 3650 \
  -subj "/CN=Begona CA" -out ca2.crt 2>/dev/null

openssl verify -CAfile ca2.crt srv.crt 2>&1
Natija
C=UZ, O=Namuna, CN=xizmat.namuna.uz
error 20 at 0 depth lookup: unable to get local issuer certificate
error srv.crt: verification failed
Terminal
# 3. Muddati o'tgan sertifikat yasaymiz
openssl x509 -req -in srv.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -not_before 20200101000000Z -not_after 20210101000000Z \
  -sha256 -extfile srv.ext -out eski.crt 2>/dev/null

openssl x509 -in eski.crt -noout -checkend 0 >/dev/null \
  && echo "eski.crt: amal qiladi" \
  || echo "eski.crt: MUDDATI OTGAN"

openssl verify -CAfile ca.crt eski.crt 2>&1
Natija
eski.crt: MUDDATI OTGAN
C=UZ, O=Namuna, CN=xizmat.namuna.uz
error 10 at 0 depth lookup: certificate has expired
error eski.crt: verification failed
Uch xato - uch xil xabar
Xato kodiMa'nosiAmaliy sabab
62Hostname mismatchSertifikat boshqa domen uchun
20Unable to get local issuer certificateMarkaz noma'lum yoki zanjir to'liq emas
10Certificate has expiredMuddati o'tgan

Ko'p dasturchi bu xatolarni ko'rganda tekshiruvni o'chirib qo'yadi:

KOD
curl -k https://...
PHP: 'verify_peer' => false
Python: verify=False

Bu eng xavfli yechim: shundan keyin har qanday soxta sertifikat qabul qilinadi va butun TLS himoyasi bekor bo'ladi.

To'g'ri yo'l - sababni aniqlash:

XatoTo'g'ri yechim
Hostname mismatchTo'g'ri domen uchun sertifikat oling
Unknown issuerOraliq sertifikatni zanjirga qo'shing
ExpiredYangilang (avtomatik yangilash sozlang)
Self-signed (sinov muhiti)O'z CA ingizni ishonchlilar ro'yxatiga qo'shing

Oxirgi qator muhim: sinov muhitida ham tekshiruvni o'chirmang - o'z CA ingizni ro'yxatga qo'shing.

Ishonch zanjiri - ildizdan saytgacha Ildiz sertifikati brauzer/OT ga OLDINDAN o'rnatilgan o'zi-imzolangan imzolaydi Oraliq sertifikat CA:TRUE - imzolashi mumkin server yuboradi imzolaydi Sayt sertifikati CN=xizmat.namuna.uz CA:FALSE - imzolay olmaydi Brauzer tekshiradi 1. Imzolar zanjiri to'g'rimi 2. Ildiz ishonchlilar ro'yxatidami 3. Muddati o'tmaganmi 4. SAN da SO'RALGAN domen bormi 5. Bekor qilinmaganmi (OCSP/CRL) Eng ko'p uchraydigan xatolar ✗ Oraliq sertifikat yuborilmagan ✗ SAN da domen yo'q (faqat CN) ✗ Muddati o'tib ketgan ✗ Tekshiruv o'chirib qo'yilgan ✗ Server vaqti noto'g'ri Ishonch qayerdan boshlanadi Zanjirning oxirida o'zi-imzolangan ildiz turadi. Uni hech kim tasdiqlamaydi. Unga ishonch oldindan o'rnatilgan ro'yxatdan keladi - brauzer va operatsion tizim bilan birga. Shuning uchun ildiz markazlar ustidan qattiq nazorat o'rnatilgan; buzilgan ildiz - butun tizimning buzilishi.
Har bo'g'in oldingisi tomonidan imzolanadi; ishonch ildizga borib taqaladi

Oraliq sertifikat va to'liq zanjir #

Real dunyoda ildiz markaz sayt sertifikatlarini to'g'ridan-to'g'ri imzolamaydi. Orada oraliq markaz turadi.

Terminal
# Ildiz oraliq markazni imzolaydi
openssl ecparam -name prime256v1 -genkey -noout -out oraliq.key 2>/dev/null
openssl req -new -key oraliq.key -subj "/C=UZ/O=Namuna/CN=Namuna Oraliq CA"   -out oraliq.csr 2>/dev/null

cat > oraliq.ext <<'EXT'
basicConstraints=critical,CA:TRUE,pathlen:0
keyUsage=critical,keyCertSign,cRLSign
EXT

openssl x509 -req -in oraliq.csr -CA ca.crt -CAkey ca.key -CAcreateserial   -days 1825 -sha256 -extfile oraliq.ext -out oraliq.crt 2>/dev/null

# Oraliq markaz server sertifikatini imzolaydi
openssl x509 -req -in srv.csr -CA oraliq.crt -CAkey oraliq.key   -CAcreateserial -days 90 -sha256 -extfile srv.ext -out srv2.crt 2>/dev/null
Terminal
echo "--- faqat ildiz bilan (oraliq yuborilmagan):"
openssl verify -CAfile ca.crt srv2.crt 2>&1

echo "--- oraliq bilan birga:"
openssl verify -CAfile ca.crt -untrusted oraliq.crt srv2.crt 2>&1
Natija
--- faqat ildiz bilan (oraliq yuborilmagan):
C=UZ, O=Namuna, CN=xizmat.namuna.uz
error 20 at 0 depth lookup: unable to get local issuer certificate
error srv2.crt: verification failed
--- oraliq bilan birga:
srv2.crt: OK
"Menda ishlaydi, lekin telefonda ishlamaydi"

Yuqoridagi ikki natija eng ko'p uchraydigan TLS muammosini ko'rsatadi.

Server faqat o'z sertifikatini yuborsa, mijoz oraliq markazni topa olmaydi va zanjirni qura olmaydi.

Nima uchun ba'zi qurilmalarda ishlaydi:

QurilmaXulqi
Brauzer (ish stoli)Oraliqni keshdan topishi mumkin
Mobil ilovaOdatda topa olmaydi - xato
curl, PHP, PythonTopa olmaydi - xato
Monitoring tizimlariTopa olmaydi - xato

Shuning uchun server konfiguratsiyasida to'liq zanjir ko'rsatilishi kerak:

KOD
ssl_certificate /etc/ssl/fullchain.pem;   # sayt + oraliq

fullchain.pem - sayt sertifikati va oraliq sertifikatlar ketma-ket yozilgan fayl. Ildizni qo'shish shart emas (mijozda allaqachon bor).

Zanjirni ko'rish #

Terminal
cat srv2.crt oraliq.crt > fullchain.pem

echo "--- fullchain ichida nechta sertifikat:"
grep -c "BEGIN CERTIFICATE" fullchain.pem

echo "--- har birining egasi va imzolovchisi:"
openssl crl2pkcs7 -nocrl -certfile fullchain.pem 2>/dev/null   | openssl pkcs7 -print_certs -noout 2>/dev/null
Natija
--- fullchain ichida nechta sertifikat:
2
--- har birining egasi va imzolovchisi:
subject=C=UZ, O=Namuna, CN=xizmat.namuna.uz
issuer=C=UZ, O=Namuna, CN=Namuna Oraliq CA

subject=C=UZ, O=Namuna, CN=Namuna Oraliq CA
issuer=C=UZ, O=Namuna Lab CA, CN=Namuna Ildiz CA

Sertifikatni bekor qilish #

Terminal
echo "Sertifikat muddatidan oldin bekor qilish usullari:"
echo
printf "%-12s %-32s %s\n" "USUL" "QANDAY ISHLAYDI" "MUAMMOSI"
printf "%-12s %-32s %s\n" "CRL" "bekor qilinganlar royxati" "katta, kech yangilanadi"
printf "%-12s %-32s %s\n" "OCSP" "har ulanishda sorov" "maxfiylik, kechikish"
printf "%-12s %-32s %s\n" "Stapling" "server javobni ozi keltiradi" "sozlash kerak"
printf "%-12s %-32s %s\n" "Qisqa muddat" "sertifikat tez eskiradi" "avtomatlashtirish shart"
Natija
Sertifikat muddatidan oldin bekor qilish usullari:

USUL         QANDAY ISHLAYDI                  MUAMMOSI
CRL          bekor qilinganlar royxati        katta, kech yangilanadi
OCSP         har ulanishda sorov              maxfiylik, kechikish
Stapling     server javobni ozi keltiradi     sozlash kerak
Qisqa muddat sertifikat tez eskiradi          avtomatlashtirish shart
Amaliyot qaysi tomonga ketdi

Bekor qilish tarixan ishlamagan mexanizm:

  • CRL fayllari megabaytlarga yetadi va kech yangilanadi
  • OCSP so'rovi qo'shimcha kechikish va maxfiylik muammosi keltiradi
  • Brauzerlar OCSP javob bermasa, ko'pincha ulanishga ruxsat beradi (soft-fail) - ya'ni hujumchi javobni to'sib qo'yishi kifoya

Shuning uchun soha boshqa yo'lni tanladi: sertifikat muddatini qisqartirish.

YilOdatiy muddat
20103-5 yil
20182 yil
20201 yil
Hozir90 kun (Let's Encrypt)

Mantiq oddiy: sertifikat 90 kunda o'z-o'zidan eskiradi, demak bekor qilish deyarli kerak emas.

Buning sharti - avtomatik yangilash. Qo'lda yangilash 90 kunlik muddat bilan amalda mumkin emas.

Sertifikatni PHP da tekshirish #

Terminal
cat > tekshir.php <<'PHP'
<?php
declare(strict_types=1);

$pem = file_get_contents('srv.crt');
$malumot = openssl_x509_parse($pem);

printf("subject CN:  %s\n", $malumot['subject']['CN']);
printf("issuer CN:   %s\n", $malumot['issuer']['CN']);
printf("SAN:         %s\n", $malumot['extensions']['subjectAltName']);
printf("CA mi:       %s\n", $malumot['extensions']['basicConstraints']);
printf("imzo algo:   %s\n", $malumot['signatureTypeSN']);

// Muddat tekshiruvi - vaqtga bog'liq, shuning uchun mantiqiy javob
$hozir = time();
$amal = $hozir >= $malumot['validFrom_time_t']
     && $hozir <= $malumot['validTo_time_t'];
printf("amal qiladi: %s\n", $amal ? 'ha' : 'yoq');
PHP

php tekshir.php
Natija
subject CN:  xizmat.namuna.uz
issuer CN:   Namuna Ildiz CA
SAN:         DNS:xizmat.namuna.uz, DNS:www.xizmat.namuna.uz
CA mi:       CA:FALSE
imzo algo:   ecdsa-with-SHA256
amal qiladi: ha
openssl_x509_parse tekshirmaydi

Bu funksiya sertifikatni faqat o'qiydi. U:

QiladiQilmaydi
Maydonlarni ajratadiImzoni tekshirmaydi
Sanalarni beradiZanjirni qurmaydi
Kengaytmalarni ko'rsatadiDomen mosligini tekshirmaydi
Bekor qilinganini bilmaydi

Ya'ni openssl_x509_parse natijasiga qarab qaror qabul qilish - xavfsizlik xatosi. Sertifikat ichidagi nomni hujumchi xohlagancha yozishi mumkin.

PHP da haqiqiy tekshiruv oqim konteksti orqali bo'ladi:

KOD
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true,
    'verify_peer_name' => true,
    'cafile' => '/etc/ssl/certs/ca-certificates.crt',
]]);

verify_peer va verify_peer_name - ikkalasi ham kerak. Birinchisi zanjirni, ikkinchisi domenni tekshiradi.

Ularni false qilish - butun himoyani o'chirish demakdir.

Amaliy topshiriq
  1. Sinov sertifikat markazini yarating.
  2. Server kaliti va CSR yasang.
  3. SAN kengaytmasi bilan sertifikat imzolang.
  4. openssl verify bilan zanjirni tekshiring.
  5. Noto'g'ri domen so'rab, xato kodini yozing.
  6. Begona CA bilan tekshirib, xato kodini yozing.
  7. Muddati o'tgan sertifikat yasang va natijani ko'ring.
  8. Oraliq markaz qo'shing va oraliqsiz tekshirishga urinib ko'ring.
  9. fullchain.pem yasang va ichidagi sertifikatlarni sanang.
  10. openssl_x509_parse nima uchun tekshiruv emasligini tushuntiring.

Xulosa #

  • Sertifikat - ochiq kalit va shaxsni bog'lovchi imzolangan hujjat.
  • Uni sertifikat markazi (CA) imzolaydi.
  • CSR ichida maxfiy kalit yo'q - faqat ochiq kalit va so'ralayotgan nom.
  • Maxfiy kalit hech qachon serverdan chiqmaydi.
  • Domen faqat subjectAltName dan olinadi; CN eskirgan.
  • basicConstraints=CA:FALSE sertifikatning boshqalarni imzolashiga yo'l qo'ymaydi.
  • Tekshiruv beshta narsani qamraydi: zanjir, ishonch, muddat, domen, bekor qilinganlik.
  • Server to'liq zanjirni (fullchain) yuborishi shart, aks holda ba'zi mijozlarda xato chiqadi.
  • Bekor qilish mexanizmlari zaif - shuning uchun muddat 90 kunga qisqartirilgan.
  • openssl_x509_parse faqat o'qiydi, tekshirmaydi - unga qarab qaror qabul qilmang.

Keyingi bo'limda bularning hammasi birlashadigan joyni - TLS ni 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.