Certificate Pinning: co to jest, mechanizm i sposoby mocowania

Autor: IT Sectr Opublikowano: 2026-03-09 Czas czytania: 8 min

Certificate Pinning — mechanizm mocowania certyfikatu lub klucza publicznego serwera, w którym aplikacja używa wcześniej znanego odcisku do weryfikacji połączenia HTTPS. W przeciwieństwie do standardowego łańcucha zaufania przez CA, pinning gwarantuje, że nawet skompromitowany urząd certyfikacji nie będzie mógł wydać podstawionego certyfikatu dla Twojej domeny. Według OWASP MSTG (2025), Certificate Pinning znajduje się na liście obowiązkowych kontroli dla aplikacji o poziomie ochrony L2. Implementacja obejmuje przechowywanie skrótów certyfikatów w kodzie i weryfikację przy każdym żądaniu.

Najważniejsze

  • Certificate Pinning — technika, w której aplikacja ufa tylko certyfikatowi z wcześniej znanym odciskiem, ignorując cały łańcuch CA
  • Public Key Pinning — alternatywa, mocująca tylko klucz publiczny, co upraszcza rotację przy zmianie certyfikatu
  • HPKP (HTTP Public Key Pinning) — przestarzały standard na poziomie nagłówków HTTP, niezalecany dla nowych projektów
  • Backup pins — zapasowe odciski, zapewniające ciągłość połączenia przy zmianie lub wygaśnięciu głównego certyfikatu
  • Implementacja na iOS przez SecTrustEvaluate, na Android przez CertificatePinner w OkHttp lub TrustManager

Co to jest Certificate Pinning?

Certificate Pinning — to technika bezpieczeństwa, w której aplikacja przechowuje odcisk (fingerprint) zaufanego certyfikatu i używa go jako jedynego kryterium do ustanowienia połączenia HTTPS. W standardowym modelu TLS klient sprawdza, czy certyfikat serwera jest podpisany przez zaufany główny CA — dowolny z setek wstępnie zainstalowanych w systemie urzędów. Certificate Pinning zastępuje ten łańcuch bezpośrednim sprawdzeniem: certyfikat musi pasować do zapisanego wzorca lub zawierać oczekiwany klucz publiczny.

Problem standardowego modelu stał się oczywisty po incydentach z kompromitacją CA — DigiNotar (2011), Comodo (2011), TrustCor (2022). Jeśli CA wydaje podstawiony certyfikat dla Twojej domeny, przeglądarka lub aplikacja akceptuje go jako ważny. Certificate Pinning zapobiega temu atakowi: nawet idealnie podpisany podstawiony certyfikat zostanie odrzucony, ponieważ jego odcisk nie pasuje do ustalonego w aplikacji.

Termin pinning pochodzi od pin — „kołek” lub „mocowanie”: programista mocuje zaufany certyfikat, a każde odstępstwo od niego blokuje połączenie. Według badań Mitre CWE-295, niewłaściwa walidacja certyfikatu pozostaje jednym z top-10 najniebezpieczniejszych błędów bezpieczeństwa w aplikacjach mobilnych, a Certificate Pinning jest bezpośrednią metodą jej zapobiegania.

Historia i ewolucja Certificate Pinning

Początkowo Certificate Pinning był używany w przeglądarkach poprzez mechanizm HPKP (HTTP Public Key Pinning), standaryzowany w RFC 7469. Programista wysyłał nagłówek HTTP Public-Key-Pins ze skrótami oczekiwanych kluczy, a przeglądarka zapamiętywała je na określony czas. Jednak HPKP okazał się niebezpieczny: jeden błąd w konfiguracji mógł zablokować stronę na miesiące. W 2018 roku Chrome zakończył wsparcie dla HPKP i obecnie standardem stała się implementacja programowa po stronie klienta — wewnątrz aplikacji mobilnej lub rozszerzenia przeglądarki.

Jak działa Certificate Pinning?

Proces Certificate Pinning obejmuje trzy kluczowe etapy: obliczanie odcisku, weryfikację przy połączeniu i obsługę błędu. Na etapie przygotowania programista pobiera skrót SHA-256 certyfikatu lub klucza publicznego serwera produkcyjnego. Dla aplikacji zgodnych z GDPR i PCI DSS wymagane jest również ustalenie odcisków pośrednich CA w łańcuchu.

Przy każdym żądaniu HTTPS aplikacja przechwytuje callback uwierzytelniania TLS, wyodrębnia certyfikat serwera i oblicza jego skrót SHA-256. Ten skrót jest porównywany z zapisaną listą zaufanych odcisków. Jeśli znaleziono zgodność — połączenie jest kontynuowane. Jeśli nie — aplikacja musi zerwać połączenie i zgłosić błąd, nie ujawniając szczegółów implementacji atakującemu.

kotlin
fun validateCertificate(certificate: X509Certificate,
    expectedHash: String): Boolean {
    val digest = MessageDigest.getInstance("SHA-256")
    val hash = Base64.encodeToString(
        digest.digest(certificate.publicKey.getEncoded()),
        Base64.DEFAULT
    ).trim()
    return hash == expectedHash
}

Funkcja przyjmuje obiekt X509Certificate od serwera i oczekiwany skrót. Najpierw wyodrębniany jest klucz publiczny certyfikatu, obliczany skrót SHA-256 i kodowany w Base64. Wynik jest porównywany z oczekiwanym odciskiem. W produkcji warto dodać sprawdzenie względem tablicy 2–3 odcisków dla wsparcia rotacji.

Certificate Pinning vs Public Key Pinning

Przy implementacji pinning należy wybrać, który konkretnie obiekt kryptograficzny mocować. Certificate Pinning przywiązuje się do samego certyfikatu X.509 — jego numeru seryjnego, okresu ważności i całego łańcucha. Public Key Pinning mocuje tylko klucz publiczny wewnątrz certyfikatu, ignorując pozostałe pola. Wybór znacząco wpływa na koszty operacyjne.

KryteriumCertificate PinningPublic Key Pinning
Obiekt mocowaniaCertyfikat X.509 w całościKlucz publiczny RSA/ECDSA
RotacjaWymaga aktualizacji przy każdym ponownym wydaniuNie zmienia się przy zmianie certyfikatu z tym samym kluczem
BezpieczeństwoMaksymalnie precyzyjne mocowanieMniej wrażliwy na szczegóły
ElastycznośćNiska — certyfikaty zmieniają się co 1–2 lataWysoka — klucze mogą żyć 5–10 lat
ZalecenieDla systemów krytycznych z kontrolowanymi aktualizacjamiDla większości aplikacji mobilnych i API

Public Key Pinning — preferowany wybór dla większości projektów. Klucze publiczne serwerów zwykle pozostają niezmienione przy ponownym wydaniu certyfikatu — firma po prostu podpisuje stary klucz nowym certyfikatem. Oznacza to, że aplikacja nie wymaga aktualizacji po zmianie certyfikatu, jeśli para kluczy się nie zmieniła. Certificate Pinning jest natomiast zalecany dla scenariuszy, gdzie programista w pełni kontroluje zarówno serwer, jak i kod kliencki, na przykład w aplikacjach korporacyjnych ze ścisłym cyklem aktualizacji.

Trust On First Use (TOFU)

TOFU — strategia, w której Certificate Pinning nie jest konfigurowany z góry, ale zapamiętuje certyfikat przy pierwszym połączeniu z serwerem. To podejście jest wygodne dla aplikacji, które nie wiedzą z góry, z jakim serwerem będą się łączyć. Wadą jest podatność na pierwszy atak: jeśli pierwsze połączenie zostało przechwycone, podstawiony certyfikat zostanie zaakceptowany jako zaufany. TOFU jest stosowane w połączeniach SSH i niektórych protokołach P2P.

Implementacja na iOS i Android

Na obu platformach Certificate Pinning jest implementowany przez przechwycenie połączenia TLS na poziomie stosu sieciowego. Na iOS używany jest delegat URLSession lub Alamofire ServerTrustManager. Na Android preferowanym sposobem jest OkHttp CertificatePinner, który jest wbudowany w popularne klienty HTTP i obsługuje konfigurację wielu odcisków dla każdej domeny.

swift
func validate(serverTrust: SecTrust,
    pinnedHash: String) -> Bool {
    guard let certificates = SecTrustCopyCertificateChain(serverTrust)
        as? [SecCertificate] else { return false }

    for certificate in certificates {
        let data = SecCertificateCopyData(certificate)
        var hash = Data(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        data.withUnsafeBytes {
            CC_SHA256($0.baseAddress,
                CC_LONG(data.count), &hash)
        }
        if hash.base64EncodedString() == pinnedHash {
            return true
        }
    }
    return false
}

W funkcji Swift z serverTrust wyodrębniany jest łańcuch certyfikatów, dla każdego obliczany jest skrót SHA-256, a wynik porównywany z oczekiwanym. Przejście przez wszystkie certyfikaty w łańcuchu pozwala zaimplementować pinning na poziomie pośredniego CA — jeśli pośredni certyfikat pasuje, połączenie jest akceptowane. Daje to elastyczność przy rotacji certyfikatów leaf.

TrustManager dla Android (niestandardowy)

Jeśli aplikacja nie używa OkHttp, Certificate Pinning można zaimplementować przez niestandardowy X509TrustManager. Ta metoda wymaga więcej kodu, ale daje pełną kontrolę nad procesem weryfikacji. TrustManager nadpisuje metodę checkServerTrusted, gdzie programista ręcznie sprawdza certyfikaty serwera i podejmuje decyzję o zaufaniu. Zalecane tylko dla specyficznych scenariuszy, gdzie biblioteka OkHttp jest niedostępna.

Błędy przy wdrażaniu Certificate Pinning

Najczęstszym błędem jest brak backup pins. Programista umieszcza jeden odcisk certyfikatu, a po jego wygaśnięciu użytkownicy masowo tracą połączenie. Minimalnie dopuszczalna konfiguracja to dwa odciski: bieżący certyfikat i zapasowy. Optymalnie — trzy: bieżący, zapasowy i odcisk głównego CA jako fallback.

Drugim błędem jest przechowywanie pinów w otwartej postaci w kodzie. Atakujący z dostępem do APK lub IPA może łatwo wyodrębnić odciski i je podmienić. Zaleca się obfuskację skrótów: podzielenie stringa na części, przechowywanie w zasobach z szyfrowaniem lub obliczanie przez runtime. Dla Android skuteczny jest ProGuard z obfuskacją stałych stringowych.

Trzecim błędem jest pinning na poziomie certyfikatu developerskiego. Certyfikaty deweloperskie i produkcyjne są zwykle różne, ale programiści często zapominają przełączyć piny przy budowaniu wydania. Rezultat — aplikacja produkcyjna nie może połączyć się z serwerem. Rozwiązanie — oddzielna konfiguracja pinów dla debug i release przez BuildConfig lub zasoby specyficzne dla wariantu.

  • Ignoring certificate chain — sprawdzanie tylko certyfikatu leaf bez uwzględnienia pośrednich CA, co łamie połączenie przy rotacji
  • Hardcoded dates — na sztywno zapisane daty wygaśnięcia certyfikatów, które nie zmieniają się po aktualizacji
  • No monitoring — brak alertów o błędach Certificate Pinning, przez co problemy są wykrywane dopiero od użytkowników
  • TOFU bez walidacji — użycie Trust On First Use bez dodatkowej weryfikacji, pozwalające pierwszemu atakowi MITM na ustalenie podstawionego certyfikatu

Często zadawane pytania

Czym Certificate Pinning różni się od SSL Pinning?

SSL Pinning — ogólny termin dla przywiązania do certyfikatu SSL/TLS. Certificate Pinning — konkretna implementacja, mocująca sam certyfikat X.509, a nie tylko klucz publiczny. Różnica w obiekcie mocowania: certyfikat vs klucz.

Jak bezpiecznie przechowywać odciski certyfikatów w aplikacji?

Zaleca się przechowywanie skrótów w zasobach z obfuskacją przez ProGuard (Android) lub zaszyfrowane przez Keychain (iOS). Unikaj przechowywania pinów w otwartej postaci w strings.xml lub Info.plist bez szyfrowania.

Jak często należy zmieniać przypięte odciski?

Przy każdej zmianie certyfikatu na serwerze. Zaleca się dodanie nowego odcisku jako backup pin na 3–6 miesięcy przed wygaśnięciem bieżącego, a po rotacji usunięcie starego. Minimum jeden backup pin jest obowiązkowy.

Czy można wyłączyć Certificate Pinning do debugowania?

Tak, przez kompilację warunkową: w buildzie debug pinning jest wyłączony, w release — włączony. Użyj BuildConfig.DEBUG na Android lub #if DEBUG na iOS do przełączania. Nigdy nie rób tego przez flagę runtime dostępną dla użytkownika.

Co zrobić, jeśli certyfikat został skompromitowany?

Natychmiast wydać aktualizację aplikacji z nowymi odciskami i opublikować ją w sklepach. Użyć mechanizmu wymuszonej aktualizacji. Jeśli backup pins zawierały odcisk zapasowego CA, tymczasowo można przełączyć się na inną domenę z innym certyfikatem.

Podsumowanie

  • Certificate Pinning — mocowanie zaufanego certyfikatu lub jego klucza publicznego w celu ochrony przed atakami MITM przez podstawione CA
  • Dwa podejścia — certificate pinning (ścisłe, do certyfikatu) i public key pinning (elastyczne, do klucza publicznego)
  • Backup pins obowiązkowe — minimum 2 odciski dla zapewnienia ciągłości przy rotacji certyfikatów
  • OkHttp CertificatePinner — standardowy sposób implementacji na Android z obsługą wielu pinów
  • URLSessionDelegate — główny sposób na iOS z ręcznym sprawdzaniem SecTrust i skrótów SHA-256
  • Błędy — brak backup pins, przechowywanie bez obfuskacji, pomylenie konfiguracji debug/release
  • Zalecenie — używać public key pinning dla większości projektów i Certificate Pinning tylko dla systemów krytycznych

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również