Certificate Pinning: co to je, mechanismus a způsoby fixace

Autor: IT Sectr Publikováno: 2026-03-09 Doba čtení: 8 min

Certificate Pinning — mechanismus fixace certifikátu nebo veřejného klíče serveru, při kterém aplikace používá předem známý otisk pro ověření HTTPS spojení. Na rozdíl od standardního řetězce důvěry prostřednictvím CA, pinning zaručuje, že ani kompromitovaná certifikační autorita nebude moci vydat falešný certifikát pro vaši doménu. Podle OWASP MSTG (2025) je Certificate Pinning na seznamu povinných kontrol pro aplikace úrovně ochrany L2. Implementace zahrnuje ukládání hashů certifikátů v kódu a ověřování při každém požadavku.

Hlavní body

  • Certificate Pinning — technika, při které aplikace důvěřuje pouze certifikátu s předem známým otiskem, ignorujíc celý řetězec CA
  • Public Key Pinning — alternativa, která fixuje pouze veřejný klíč, což zjednodušuje rotaci při změně certifikátu
  • HPKP (HTTP Public Key Pinning) — zastaralý standard na úrovni HTTP hlaviček, nedoporučuje se pro nové projekty
  • Backup pins — záložní otisky, které zajišťují kontinuitu spojení při změně nebo vypršení hlavního certifikátu
  • Implementace na iOS pomocí SecTrustEvaluate, na Android pomocí CertificatePinner v OkHttp nebo TrustManager

Co je Certificate Pinning?

Certificate Pinning — bezpečnostní technika, při které aplikace ukládá otisk (fingerprint) důvěryhodného certifikátu a používá jej jako jediné kritérium pro navázání HTTPS spojení. Ve standardním modelu TLS klient kontroluje, zda je certifikát serveru podepsán důvěryhodnou kořenovou CA — kteroukoliv ze stovek předinstalovaných autorit v systému. Certificate Pinning nahrazuje tento řetězec přímou kontrolou: certifikát se musí shodovat s uloženým vzorkem nebo obsahovat očekávaný veřejný klíč.

Problém standardního modelu se stal zřejmým po incidentech kompromitace CA — DigiNotar (2011), Comodo (2011), TrustCor (2022). Pokud CA vydá falešný certifikát pro vaši doménu, prohlížeč nebo aplikace jej přijme jako platný. Certificate Pinning tomuto útoku brání: i dokonale podepsaný falešný certifikát bude odmítnut, protože jeho otisk neodpovídá tomu fixovanému v aplikaci.

Termín pinning pochází z pin — „špendlík“ nebo „ fixátor“: vývojář fixuje důvěryhodný certifikát a jakákoli odchylka od něj blokuje spojení. Podle výzkumu Mitre CWE-295 zůstává nesprávná validace certifikátů jednou z top-10 nejnebezpečnějších bezpečnostních chyb v mobilních aplikacích a Certificate Pinning je přímou metodou její prevence.

Historie a vývoj Certificate Pinning

Původně byl Certificate Pinning používán v prohlížečích prostřednictvím mechanismu HPKP (HTTP Public Key Pinning), standardizovaného v RFC 7469. Vývojář odesílal HTTP hlavičku Public-Key-Pins s hashi očekávaných klíčů a prohlížeč si je pamatoval po stanovenou dobu. HPKP se však ukázal jako nebezpečný: jedna chyba v konfiguraci mohla zablokovat web na měsíce. V roce 2018 Chrome ukončil podporu HPKP a nyní je standardem softwarová implementace na straně klienta — uvnitř mobilní aplikace nebo rozšíření prohlížeče.

Jak funguje Certificate Pinning?

Proces Certificate Pinning zahrnuje tř9i klíčové fáze: výpočet otisku, ověření při připojení a zpracování chyby. Ve fázi přípravy vývojář získá SHA-256 hash certifikátu nebo veřejného klíče produkčního serveru. Pro aplikace vyhovující GDPR a PCI DSS je také nutné fixovat otisky prostředních CA v řetězci.

Při každém HTTPS požadavku aplikace zachytí callback autentizace TLS, extrahuje certifikát serveru a vypočítá jeho SHA-256 hash. Tento hash je porovnán s uloženým seznamem důvěryhodných otisků. Pokud je nalezena shoda — spojení pokračuje. Pokud ne — aplikace musí přerušit spojení a ohlásit chybu, aniž by prozradila detaily implementace útočníkovi.

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
}

Funkce přijímá objekt X509Certificate od serveru a očekávaný hash. Nejprve se extrahuje veřejný klíč certifikátu, vypočítá se SHA-256 hash a zakóduje se do Base64. Výsledek se porovná s očekávaným otiskem. V produkci stojí za to přidat kontrolu na pole 2–3 otisků pro podporu rotace.

Certificate Pinning vs Public Key Pinning

Při implementaci pinningu je třeba zvolit, který kryptografický objekt fixovat. Certificate Pinning se váže na samotný certifikát X.509 — jeho sériové číslo, dobu platnosti a celý řetězec. Public Key Pinning fixuje pouze veřejný klíč uvnitř certifikátu, ignorujíc ostatní pole. Volba významně ovlivňuje provozní náklady.

KritériumCertificate PinningPublic Key Pinning
Objekt fixaceCertifikát X.509 celýVeřejný klíč RSA/ECDSA
RotaceVyžaduje aktualizaci při každém novém vydáníNemění se při změně certifikátu se stejným klíčem
BezpečnostMaximálně přesné vázáníMéně citlivé na detaily
FlexibilitaNízká — certifikáty se mění každý 1–2 rokyVysoká — klíče mohou žít 5–10 let
DoporučeníPro kritické systémy s řízenými aktualizacemiPro většinu mobilních aplikací a API

Public Key Pinning — preferovaná volba pro většinu projektů. Veřejné klíče serverů obvykle zůstávají nezměněny při novém vydání certifikátu — společnost jednoduše podepíše starý klíč novým certifikátem. To znamená, že aplikace nevyžaduje aktualizaci po změně certifikátu, pokud se pár klíčů nezměnil. Certificate Pinning se doporučuje pro scénáře, kde vývojář plně kontroluje jak server, tak klientský kód, například v podnikových aplikacích s přísným cyklem aktualizací.

Trust On First Use (TOFU)

TOFU — strategie, při které Certificate Pinning není předem nakonfigurován, ale pamatuje si certifikát při prvním připojení k serveru. Tento přístup je vhodný pro aplikace, které předem nevědí, ke kterému serveru se připojí. Nevýhoda — zranitelnost při prvním útoku: pokud je první spojení zachyceno, falešný certifikát bude přijat jako důvěryhodný. TOFU se používá v SSH připojeních a některých P2P protokolech.

Implementace na iOS a Android

Na obou platformách je Certificate Pinning implementován zachycením TLS spojení na úrovni síťového zásobníku. Na iOS se používá delegát URLSession nebo Alamofire ServerTrustManager. Na Android je preferovaným způsobem OkHttp CertificatePinner, který je integrován v populárních HTTP klientech a podporuje konfiguraci více otisků pro každou doménu.

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
}

Ve funkci Swift je ze serverTrust extrahován řetězec certifikátů, pro každý je vypočítán SHA-256 hash a výsledek porovnán s očekávaným. Průchod všemi certifikáty v řetězci umožňuje implementovat pinning na úrovni prostřední CA — pokud se prostřední certifikát shoduje, spojení je přijato. To poskytuje flexibilitu při rotaci leaf certifikátů.

TrustManager pro Android (vlastní)

Pokud aplikace nepoužívá OkHttp, lze Certificate Pinning implementovat prostřednictvím vlastního X509TrustManager. Tato metoda vyžaduje více kódu, ale poskytuje úplnou kontrolu nad procesem ověřování. TrustManager přepisuje metodu checkServerTrusted, kde vývojář ručně kontroluje certifikáty serveru a rozhoduje o důvěře. Doporučuje se pouze pro specifické scénáře, kde knihovna OkHttp není k dispozici.

Chyby při implementaci Certificate Pinning

Nejčastější chyba — chybějící záložní piny. Vývojář umístí jeden otisk certifikátu a při jeho vypršení uživatelé hromadně ztrácejí spojení. Minimálně přijatelná konfigurace — dva otisky: aktuální certifikát a záložní. Optimální — tři: aktuální, záložní a otisk kořenové CA jako fallback.

Druhá chyba — ukládání pinů v otevřené podobě v kódu. Útočník s přístupem k APK nebo IPA může snadno extrahovat a nahradit otisky. Doporučuje se obfuskace hashů: rozdělit řetězec na části, ukládat v šifrovaných zdrojích nebo počítat za běhu. Pro Android je účinný ProGuard s obfuskací řetězcových konstant.

Třetí chyba — pinning na úrovni development certifikátu. Vývojové a produkční certifikáty jsou obvykle odlišné, ale vývojáři často zapomínají přepnout piny při sestavování release. Výsledek — produkční aplikace se nemůže připojit k serveru. Řešení — oddělená konfigurace pinů pro debug a release pomocí BuildConfig nebo prostředků specifických pro flavour.

  • Ignoring certificate chain — kontrola pouze leaf certifikátu bez zohlednění prostředních CA, což přerušuje spojení při rotaci
  • Hardcoded dates — tvrdě zakódovaná data vypršení certifikátů, která se po aktualizaci nemění
  • No monitoring — chybějící upozornění na chyby Certificate Pinning, kvůli čemuž jsou problémy objeveny pouze od uživatelů
  • TOFU bez validace — použití Trust On First Use bez další kontroly, umožňující prvnímu MITM útoku fixovat falešný certifikát

Často kladené otázky

Čím se Certificate Pinning liší od SSL Pinning?

SSL Pinning — obecný termín pro vázání na SSL/TLS certifikát. Certificate Pinning — konkrétní implementace, která fixuje samotný certifikát X.509, nejen veřejný klíč. Rozdíl je v objektu fixace: certifikát vs klíč.

Jak bezpečně ukládat otisky certifikátů v aplikaci?

Doporučuje se ukládat hashe ve zdrojích s obfuskací pomocí ProGuard (Android) nebo šifrovaně pomocí Keychain (iOS). Vyhněte se ukládání pinů v otevřené podobě v strings.xml nebo Info.plist bez šifrování.

Jak často je třeba měnit pinned otisky?

Při každé změně certifikátu na serveru. Doporučuje se přidání nového otisku jako záložního pin 3–6 měsíců před vypršením aktuálního a po rotaci odstranění starého. Minimálně jeden záložní pin je povinný.

Lze Certificate Pinning vypnout pro ladění?

Ano, pomocí podmíněné kompilace: v debug sestavení je pinning vypnutý, v release — zapnutý. Použijte BuildConfig.DEBUG na Android nebo #if DEBUG na iOS pro přepínání. Nikdy to nedělejte pomocí runtime příznaku přístupného uživateli.

Co dělat, když je certifikát kompromitován?

Okamžitě vydat aktualizaci aplikace s novými otisky a publikovat ji v obchodech. Použít mechanismus vynucené aktualizace. Pokud záložní piny zahrnovaly otisk záložní CA, dočasně lze přejít na jinou doménu s jiným certifikátem.

Shrnutí

  • Certificate Pinning — fixace důvěryhodného certifikátu nebo jeho veřejného klíče pro ochranu proti MITM útokům prostřednictvím falešných CA
  • Dva přístupy — certificate pinning (přísný, k certifikátu) a public key pinning (flexibilní, k veřejnému klíči)
  • Záložní piny povinné — minimálně 2 otisky pro zajištění kontinuity při rotaci certifikátů
  • OkHttp CertificatePinner — standardní způsob implementace na Android s podporou více pinů
  • URLSessionDelegate — hlavní způsob na iOS s ruční kontrolou SecTrust a SHA-256 hashů
  • Chyby — chybějící záložní piny, ukládání bez obfuskace, záměna debug/release konfigurací
  • Doporučení — používejte public key pinning pro většinu projektů a Certificate Pinning pouze pro kritické systémy

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také