Tarkibga o'tish

HTTPS nima

HTTPS (HTTP Secure) — TLS protokoli orqali himoyalangan HTTP. So‘rov va javoblarning o‘zi o‘zgarmaydi: xuddi o‘sha metodlar, sarlavhalar va JSON tanasi. Farqi shundaki, ular tarmoqqa chiqishdan oldin shifrlanadi va faqat haqiqiy server ularni ocha oladi.

TLS (Transport Layer Security) — shifrlangan kanal quradigan protokol. Uning eski nomi SSL. SSL versiyalari allaqachon xavfsiz emas deb topilgan va ishlatilmaydi, lekin "SSL sertifikat" iborasi hanuzgacha ko‘p uchraydi.

┌────────────────────┐
│ HTTP               │  so‘rov va javoblar
├────────────────────┤
│ TLS                │  shifrlash, yaxlitlik, server haqiqiyligi
├────────────────────┤
│ TCP                │  ishonchli uzatish
├────────────────────┤
│ IP                 │  manzil bo‘yicha yo‘naltirish
└────────────────────┘

HTTP odatda 80-portda, HTTPS esa 443-portda ishlaydi.

Ikki xil shifrlash

TLS ikki turdagi shifrlashni birlashtiradi. Nima uchun ikkalasi ham kerakligini tushunish uchun avval ularni alohida ko‘rib chiqamiz.

Simmetrik shifrlash

Shifrlash va ochish uchun bitta kalit ishlatiladi. Xuddi eshik qulfiga o‘xshaydi: qaysi kalit bilan qulflasangiz, o‘sha kalit bilan ochasiz.

"Salom" + kalit → "x7#kQ" → "x7#kQ" + kalit → "Salom"
  • ✅ juda tez, katta hajmdagi ma’lumot uchun mos;
  • ❌ muammo: kalitni boshqa tomonga qanday xavfsiz yetkazish kerak? Uni ochiq tarmoq orqali yuborib bo‘lmaydi, chunki yo‘lda ushlab olinishi mumkin.

Misollar: AES, ChaCha20.

Asimmetrik shifrlash

Juft kalit ishlatiladi: ochiq kalit (public key) va yopiq kalit (private key). Ochiq kalit bilan shifrlangan ma’lumotni faqat yopiq kalit ochadi. Yopiq kalit bilan qo‘yilgan imzoni esa istalgan odam ochiq kalit bilan tekshira oladi.

Buni pochta qutisiga o‘xshatish mumkin. Qutidagi tirqishga istalgan odam xat tashlashi mumkin, bu — ochiq kalit. Qutini esa faqat egasi o‘z kaliti bilan ocha oladi, bu — yopiq kalit.

  • ✅ kalitni oldindan uzatish muammosi yo‘q: ochiq kalitni hammaga tarqatish mumkin;
  • ❌ sekin, katta hajmdagi ma’lumot uchun noqulay.

Misollar: RSA, ECDSA, Ed25519.

TLS ikkalasini birlashtiradi

  1. Ulanish boshida asimmetrik kriptografiya yordamida ikki tomon umumiy maxfiy kalit bo‘yicha kelishib oladi. Bu kalit tarmoq orqali uzatilmaydi, har bir tomon uni o‘zi hisoblaydi.
  2. Keyingi barcha ma’lumot shu umumiy kalit bilan simmetrik shifrlanadi.

Natijada kalitni uzatish muammosi hal bo‘ladi va ma’lumotni shifrlash tez ishlaydi.

TLS handshake

HTTPS ulanishi o‘rnatilishidan oldin klient va server handshake (qo‘l siqishish) jarayonini bajaradi. TLS 1.3 da u qisqartirilgan va bitta aylanishda tugaydi:

Klient                                          Server
  │                                               │
  │── ClientHello ──────────────────────────────▶ │
  │   • qo‘llab-quvvatlanadigan TLS versiyalari    │
  │   • shifrlar ro‘yxati                         │
  │   • kalit almashish uchun ochiq qiymat        │
  │   • server nomi (SNI): api.example.uz         │
  │                                               │
  │ ◀──────────────────────────────── ServerHello │
  │   • tanlangan shifr                           │
  │   • kalit almashish uchun ochiq qiymat        │
  │   • sertifikat                               │
  │   • sertifikat egasi ekanini isbotlovchi imzo │
  │                                               │
  │  Ikkala tomon umumiy kalitni hisoblaydi       │
  │                                               │
  │═══════ shifrlangan HTTP so‘rov va javob ═════ │

Handshake davomida uchta muhim ish bajariladi:

  1. Kelishuv. Ikkala tomon qo‘llab-quvvatlaydigan TLS versiyasi va shifr tanlanadi.
  2. Kalit almashish. Ikkala tomon umumiy maxfiy kalitni hisoblaydi. Uni tarmoqni kuzatayotgan odam hisoblay olmaydi.
  3. Server haqiqiyligini tekshirish. Klient server sertifikatini tekshiradi va server shu sertifikatning yopiq kalitiga egaligini isbotlaydi.

SNI (Server Name Indication) — klient qaysi domenga ulanmoqchi ekanini handshake boshida aytadi. Bitta IP manzilda bir nechta domen joylashgan bo‘lsa, server shu nomga qarab to‘g‘ri sertifikatni tanlaydi.

Sertifikat

Kalit almashish shifrlangan kanal hosil qiladi. Lekin bu kanal kim bilan qurilganini qanday bilamiz? Hujumchi o‘rtada turib, o‘zini api.example.uz deb tanishtirishi mumkin. Bu hujum man-in-the-middle (o‘rtadagi odam) deyiladi.

Sertifikat bu muammoni hal qiladi. Sertifikat — raqamli guvohnoma. Unda quyidagilar yozilgan bo‘ladi:

  • qaysi domenlar uchun berilgani (api.example.uz);
  • server ochiq kaliti;
  • amal qilish muddati;
  • kim tomonidan berilgani;
  • bergan tashkilotning raqamli imzosi.

Sertifikat pasportga o‘xshaydi. Pasportdagi rasm bu odamga tegishli ekanini, uni bergan davlat muhri esa pasport soxta emasligini tasdiqlaydi.

Sertifikat markazlari va ishonch zanjiri

Sertifikatlarni sertifikat markazlari (CA — Certificate Authority) beradi. Masalan, Let's Encrypt, DigiCert yoki GlobalSign. Operatsion tizim va brauzerlarda ishonchli ildiz sertifikatlar (root certificates) ro‘yxati oldindan o‘rnatilgan bo‘ladi.

Ildiz sertifikat serverlarga to‘g‘ridan-to‘g‘ri sertifikat bermaydi. Uning o‘rniga oraliq (intermediate) sertifikatlar orqali ishonch zanjiri quriladi:

ISRG Root X1                       ← ildiz: brauzer va OS'da oldindan bor
    │ imzolaydi
    ↓
Let's Encrypt R11                  ← oraliq sertifikat
    │ imzolaydi
    ↓
api.example.uz                     ← server sertifikati

Klient zanjirni pastdan yuqoriga tekshiradi. Server sertifikatini oraliq sertifikat imzolaganmi? Oraliq sertifikatni ildiz sertifikat imzolaganmi? Ildiz sertifikat ishonchli ro‘yxatda bormi? Barcha javoblar "ha" bo‘lsa, klient ulanishni davom ettiradi.

Server handshake paytida o‘z sertifikati bilan birga oraliq sertifikatlarni ham yuborishi kerak. Shuning uchun sertifikat fayli odatda fullchain.pem deb nomlanadi.

Klient yana nimani tekshiradi?

  • sertifikatdagi domen ulanilayotgan domenga mos keladimi;
  • sertifikat muddati tugamaganmi;
  • sertifikat bekor qilinmaganmi.

Birorta tekshiruv o‘tmasa, brauzer "Ulanish xavfsiz emas" ogohlantirishini ko‘rsatadi. curl va Go klientlari esa xato qaytaradi.

Go’da sertifikatni ko‘rish

Istalgan saytning sertifikatini Go yordamida ko‘rish mumkin:

main.go
package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "os"
    "time"
)

func main() {
    host := "go.dev"
    if len(os.Args) > 1 {
        host = os.Args[1]
    }

    conn, err := tls.Dial("tcp", host+":443", &tls.Config{ServerName: host})
    if err != nil {
        log.Fatalf("ulanib bo‘lmadi: %v", err)
    }
    defer conn.Close()

    state := conn.ConnectionState()
    fmt.Println("TLS versiyasi:", tls.VersionName(state.Version))
    fmt.Println("Shifr:        ", tls.CipherSuiteName(state.CipherSuite))
    fmt.Println()

    for i, cert := range state.PeerCertificates {
        fmt.Printf("%d. %s\n", i, cert.Subject.CommonName)
        fmt.Printf("   Bergan:   %s\n", cert.Issuer.CommonName)
        fmt.Printf("   Muddati:  %s (%d kun qoldi)\n",
            cert.NotAfter.Format(time.DateOnly), int(time.Until(cert.NotAfter).Hours()/24))
        if len(cert.DNSNames) > 0 {
            fmt.Printf("   Domenlar: %v\n", cert.DNSNames)
        }
    }
}
go run main.go go.dev
TLS versiyasi: TLS 1.3
Shifr:         TLS_AES_128_GCM_SHA256

0. go.dev
   Bergan:   WR3
   Muddati:  2026-12-20 (80 kun qoldi)
   Domenlar: [go.dev]
1. WR3
   Bergan:   GTS Root R1
   Muddati:  2029-02-20 (873 kun qoldi)
2. GTS Root R1
   Bergan:   GlobalSign Root CA
   Muddati:  2028-01-28 (484 kun qoldi)

Natija sayt va vaqtga qarab farq qiladi. Chiqishda ishonch zanjiri ko‘rinib turibdi: server sertifikati, uni bergan oraliq sertifikat va undan yuqoridagi sertifikat. Oxirgi sertifikatni esa klientdagi ishonchli ildiz sertifikat tasdiqlaydi.

tls.Dial handshake paytida zanjirni avtomatik tekshirdi. Sertifikat noto‘g‘ri bo‘lsa, dastur ulanib bo‘lmadi xatosi bilan to‘xtaydi. Masalan:

go run main.go expired.badssl.com
2026/09/30 10:00:00 ulanib bo‘lmadi: tls: failed to verify certificate: x509: certificate has expired or is not yet valid: ...

Danger

tls.Config{InsecureSkipVerify: true} sertifikat tekshiruvini butunlay o‘chiradi. Shifrlash qoladi, lekin kim bilan gaplashayotganingizni bilmaysiz. Bu man-in-the-middle hujumidan himoyani yo‘q qiladi. Uni production kodida hech qachon ishlatmang. Lokal sinov uchun ham undan ko‘ra o‘z sertifikatingizni ishonchli qilib qo‘shish to‘g‘riroq.

TLS versiyalari

Versiya Yil Holati
SSL 2.0, 3.0 1995–1996 ❌ Xavfsiz emas, taqiqlangan
TLS 1.0, 1.1 1999, 2006 ❌ Eskirgan, 2021-yilda rasman bekor qilingan
TLS 1.2 2008 ✅ Hali keng qo‘llanadi
TLS 1.3 2018 ✅ Tavsiya etiladi: tezroq va xavfsizroq

Go standart holatda TLS 1.2 va 1.3 bilan ishlaydi. Bu sozlamalar TLS konfiguratsiyasi darsida ko‘riladi.

Xulosa

  • HTTPS — TLS orqali himoyalangan HTTP. U maxfiylik, yaxlitlik va server haqiqiyligini kafolatlaydi.
  • TLS asimmetrik kriptografiya bilan kalit bo‘yicha kelishadi, ma’lumotni esa tez ishlaydigan simmetrik shifrlash bilan himoyalaydi.
  • Handshake davomida versiya va shifr tanlanadi, umumiy kalit hisoblanadi va server sertifikati tekshiriladi.
  • Sertifikat domen va ochiq kalitni bog‘laydi. Unga CA imzosi va ishonch zanjiri orqali ishoniladi.
  • InsecureSkipVerify tekshiruvni o‘chiradi. Uni production’da ishlatmang.

Keyingi darsda lokal ishlab chiqish uchun o‘z sertifikatimizni yaratib, Go serverini HTTPS’da ishga tushiramiz.