Sparround

Şəbəkə təhlükəsizliyi: TLS, certificate pinning

HTTPS/TLS trafiki şifrələyir, amma kimə etibar etdiyini sistem CA store-u müəyyən edir. Problem: istifadəçi cihazına zərərli CA quraşdırıla bilər (və ya CA-nın özü kompromis olar) → MITM (man-in-the-middle) hücumu.

Certificate pinning — tətbiq yalnız öz serverinin sertifikatına (adətən public key-in SHA-256 hash-inə) etibar edir; zəncir "etibarlı" görünsə belə, pin uyğun gəlmirsə əlaqə kəsilir.

İki icra yolu:

  • OkHttp CertificatePinner — kodda pin-lər
  • Network Security Configres/xml/network_security_config.xml-də deklarativ: pin-set + expiration, cleartext qadağası, debug-overrides

Kritik qayda — backup pin: yalnız cari sertifikatı pin-ləsən, sertifikat rotasiyasında bütün istifadəçilər kilidlənir və yalnız tətbiq yeniləməsi xilas edir. Həmişə ehtiyat açarın pin-i də əlavə olunur.

Əlavə: cleartextTrafficPermitted="false" (defolt API 28+) — HTTP tam qadağan; debug CA-lara icazə yalnız debug-overrides blokunda.

kotlin
// 1) OkHttp CertificatePinner — backup pin MÜTLƏQ
val pinner = CertificatePinner.Builder()
    .add("api.bank.example", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")  // cari
    .add("api.bank.example", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")  // ehtiyat
    .build()

val client = OkHttpClient.Builder()
    .certificatePinner(pinner)
    .build()

// 2) network_security_config.xml — deklarativ
// <network-security-config>
//   <domain-config cleartextTrafficPermitted="false">
//     <domain includeSubdomains="true">api.bank.example</domain>
//     <pin-set expiration="2027-01-01">
//       <pin digest="SHA-256">AAAA...=</pin>
//       <pin digest="SHA-256">BBBB...=</pin>
//     </pin-set>
//   </domain-config>
// </network-security-config>

İki üsulla pinning

Pin nəyə vurulur — bilməli olduğun nüans: leaf sertifikatın özünə yox, adətən public key-inə (SPKI hash) — sertifikat yenilənib açar saxlanılanda pin işlək qalır. İntermediate CA-nı pin-ləmək daha yumşaq, leaf-i pin-ləmək daha sərt siyasətdir. Pin-lərin expiration-ı təhlükəsizlik-əlçatanlıq balansıdır: vaxtı keçəndə pinning söndürülür ki, unudulmuş rotasiya tətbiqi daimi kilidləməsin.

🛠 Tapşırıq

MITM-i öz laboratoriyanda gör:

  • Charles və ya mitmproxy quraşdır, sertifikatını cihaza əlavə et və pinning olmadan tətbiqin trafikini aç.
  • Sonra CertificatePinner (və ya network security config pin-set) əlavə et — sorğunun SSLPeerUnverifiedException ilə kəsildiyini gör.
  • Debug/release ayrımını qur: debug-overrides yalnız debug build-də.

Bitdi sayılır: pinning-i əlavə edərkən backup pin qoyub "rotasiya risqi"ni izah edirsənsə.

📚 Mənbələr və sənədlər