Certificate Pinning: vad är det, mekanism och metoder för fixering

Författare: IT Sectr Publicerad: 2026-03-09 Lästid: 8 min

Certificate Pinning — en mekanism för att fixera serverns certifikat eller offentliga nyckel, där appen använder ett för känt avtryck för att verifiera HTTPS-anslutningen. Till skillnad från den standardmässiga förtroendekedjan via CA garanterar pinning att även en komprometterad certifikatutfärdare inte kan utfärda ett falskt certifikat för din domän. Enligt OWASP MSTG (2025) finns Certificate Pinning med på listan över obligatoriska kontroller för appar med skyddsnivå L2. Implementeringen innefattar lagring av certifikathashar i koden och verifiering vid varje begäran.

Huvudpunkter

  • Certificate Pinning — teknik där appen endast litar på certifikatet med ett för känt avtryck och ignorerar hela CA-kedjan
  • Public Key Pinning — alternativ som endast fixerar den offentliga nyckeln, vilket förenklar rotation vid certifikatändring
  • HPKP (HTTP Public Key Pinning) — föråldrad standard på HTTP-rubriknivå, rekommenderas inte för nya projekt
  • Backup pins — reservavtryck som säkerställer anslutningens kontinuitet vid ändring eller utgång av huvudcertifikatet
  • Implementering på iOS via SecTrustEvaluate, på Android via CertificatePinner i OkHttp eller TrustManager

Vad är Certificate Pinning?

Certificate Pinning — är en säkerhetsteknik där appen lagrar avtrycket (fingerprint) av ett betrott certifikat och använder det som det enda kriteriet för att upprätta en HTTPS-anslutning. I standard TLS-modellen kontrollerar klienten om serverns certifikat är signerat av en betrodd root-CA — någon av hundratals förinstallerade utfärdare i systemet. Certificate Pinning ersätter denna kedja med en direkt kontroll: certifikatet måste matcha det lagrade provet eller innehålla den förväntade offentliga nyckeln.

Problemet med standardmodellen blev uppenbart efter incidenter med CA-kompromettering — DigiNotar (2011), Comodo (2011), TrustCor (2022). Om en CA utfärdar ett falskt certifikat för din domän, accepterar webbläsaren eller appen det som giltigt. Certificate Pinning förhindrar denna attack: även ett perfekt signerat falskt certifikat kommer att avvisas, eftersom dess avtryck inte matchar det som fixerats i appen.

Termen pinning kommer från pin — ”nål” eller ”fixerare”: utvecklaren fixerar det betrodda certifikatet, och varje avvikelse från det blockerar anslutningen. Enligt forskning från Mitre CWE-295 förblir felaktig certifikatvalidering ett av de 10 farligaste säkerhetsfelen i mobilappar, och Certificate Pinning är den direkta metoden för att förebygga det.

Historia och utveckling av Certificate Pinning

Ursprungligen användes Certificate Pinning i webbläsare genom HPKP-mekanismen (HTTP Public Key Pinning), standardiserad i RFC 7469. Utvecklaren skickade en HTTP-rubrik Public-Key-Pins med hash av förväntade nycklar, och webbläsaren kom ihåg dem under en angiven period. HPKP visade sig dock vara farligt: ett enda konfigurationsfel kunde blockera webbplatsen i månader. 2018 slutade Chrome att stödja HPKP och nu är standarden mjukvaruimplementering på klientsidan — inuti mobilappen eller webbläsartillägget.

Hur fungerar Certificate Pinning?

Certificate Pinning-processen omfattar tre nyckelsteg: beräkning av avtryck, verifiering vid anslutning och felhantering. I förberedelsesteget får utvecklaren SHA-256-hashen av produktionsserverns certifikat eller offentliga nyckel. För GDPR- och PCI DSS-kompatibla appar krävs även fixering av avtryck från mellanliggande CA i kedjan.

Vid varje HTTPS-begäran fångar appen TLS-autentiseringscallback, extraherar serverns certifikat och beräknar dess SHA-256-hash. Denna hash jämförs med den lagrade listan över betrodda avtryck. Om en överensstämmelse hittas — fortsätter anslutningen. Om inte — måste appen avbryta anslutningen och rapportera felet, utan att avslöja implementeringsdetaljer för angriparen.

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
}

Funktionen tar emot ett X509Certificate-objekt från servern och den förväntade hashen. Först extraheras certifikatets offentliga nyckel, SHA-256-hashen beräknas och kodas i Base64. Resultatet jämförs med det förväntade avtrycket. I produktion är det värt att lägga till kontroll på en array av 2–3 avtryck för att stödja rotation.

Certificate Pinning vs Public Key Pinning

Vid implementering av pinning måste man välja vilket kryptografiskt objekt som ska fixeras. Certificate Pinning binder till själva X.509-certifikatet — dess serienummer, giltighetsperiod och hela kedjan. Public Key Pinning fixerar endast den offentliga nyckeln inuti certifikatet och ignorerar övriga fält. Valet påverkar driftskostnaderna avsevärt.

KriteriumCertificate PinningPublic Key Pinning
FixeringsobjektX.509-certifikat i sin helhetOffentlig nyckel RSA/ECDSA
RotationKräver uppdatering vid varje nyutfärdandeÄndras inte vid certifikatbyte med samma nyckel
SäkerhetMaximalt precis bindningMindre känslig för detaljer
FlexibilitetLåg — certifikat byts var 1–2 årHög — nycklar kan leva 5–10 år
RekommendationFör kritiska system med kontrollerade uppdateringarFör de flesta mobilappar och API:er

Public Key Pinning — föredraget val för de flesta projekt. Servrarnas offentliga nycklar förblir vanligtvis oförändrade vid nyutfärdande av certifikatet — företaget signerar helt enkelt den gamla nyckeln med ett nytt certifikat. Detta innebär att appen inte kräver uppdatering efter certifikatbyte, om nyckelparet inte har ändrats. Certificate Pinning rekommenderas för scenarier där utvecklaren har full kontroll över både servern och klientkoden, till exempel i företagsappar med strikt uppdateringscykel.

Trust On First Use (TOFU)

TOFU — en strategi där Certificate Pinning inte är förkonfigurerat, utan kommer ihåg certifikatet vid första anslutningen till servern. Detta tillvägagångssätt är bekvämt för appar som inte i förväg vet vilken server de ska ansluta till. Nackdelen — sårbarhet vid första attacken: om den första anslutningen fångas upp kommer det falska certifikatet att accepteras som betrott. TOFU används i SSH-anslutningar och vissa P2P-protokoll.

Implementering på iOS och Android

På båda plattformarna implementeras Certificate Pinning genom att fånga TLS-anslutningen på nätverksstacknivå. På iOS används URLSession-delegat eller Alamofire ServerTrustManager. På Android är den föredragna metoden OkHttp CertificatePinner, som är inbyggd i populära HTTP-klienter och stödjer konfiguration av flera avtryck för varje domän.

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
}

I Swift-funktionen extraheras certifikatkedjan från serverTrust, för varje beräknas SHA-256-hashen och resultatet jämförs med det förväntade. Genom att gå igenom alla certifikat i kedjan kan pinning implementeras på nivån av mellanliggande CA — om det mellanliggande certifikatet matchar, accepteras anslutningen. Detta ger flexibilitet vid rotation av leaf-certifikat.

TrustManager för Android (anpassad)

Om appen inte använder OkHttp kan Certificate Pinning implementeras via en anpassad X509TrustManager. Denna metod kräver mer kod, men ger full kontroll över verifieringsprocessen. TrustManager åsidosätter metoden checkServerTrusted, där utvecklaren manuellt kontrollerar serverns certifikat och fattar ett förtroendebeslut. Rekommenderas endast för specifika scenarier där OkHttp-biblioteket inte är tillgängligt.

Misstag vid implementering av Certificate Pinning

Det vanligaste misstaget — avsaknad av reservpins. Utvecklaren placerar ett certifikatavtryck och när det går ut förlorar användare massivt anslutningen. Den minst acceptabla konfigurationen — två avtryck: aktuellt certifikat och reserv. Optimalt — tre: aktuellt, reserv och avtryck av root-CA som fallback.

Andra misstaget — lagring av pins i öppen form i koden. En angripare med tillgång till APK eller IPA kan enkelt extrahera och ersätta avtrycken. Det rekommenderas att obfuskera hash: dela upp strängen i delar, lagra i krypterade resurser eller beräkna via runtime. För Android är ProGuard med obfuskering av strängkonstanter effektivt.

Tredje misstaget — pinning på nivån av utvecklingscertifikat. Utvecklings- och produktionscertifikat är vanligtvis olika, men utvecklare glömmer ofta att byta pins vid bygge av release. Resultatet — produktionsappen kan inte ansluta till servern. Lösning — separat pin-konfiguration för debug och release via BuildConfig eller flavourspecifika resurser.

  • Ignoring certificate chain — kontroll endast av leaf-certifikatet utan hänsyn till mellanliggande CA, vilket bryter anslutningen vid rotation
  • Hardcoded dates — hårdkodade certifikatets utgångsdatum som inte ändras efter uppdatering
  • No monitoring — avsaknad av varningar för Certificate Pinning-fel, varvid problem upptäcks endast från användare
  • TOFU utan validering — användning av Trust On First Use utan ytterligare kontroll, vilket låter den första MITM-attacken fixera ett falskt certifikat

Vanliga frågor

Vad är skillnaden mellan Certificate Pinning och SSL Pinning?

SSL Pinning — allmän term för bindning till SSL/TLS-certifikat. Certificate Pinning — konkret implementering som fixerar själva X.509-certifikatet, inte bara den offentliga nyckeln. Skillnaden ligger i fixeringsobjektet: certifikat vs nyckel.

Hur lagrar man säkert certifikatavtryck i appen?

Det rekommenderas att lagra hash i resurser med obfuskering via ProGuard (Android) eller krypterade via Keychain (iOS). Undvik att lagra pins i öppen form i strings.xml eller Info.plist utan kryptering.

Hur ofta måste pinned-avtryck bytas?

Vid varje ändring av certifikatet på servern. Det rekommenderas att lägga till ett nytt avtryck som reservpin 3–6 månader före utgången av det aktuella certifikatet, och efter rotation ta bort det gamla. Minst en reservpin är obligatorisk.

Kan Certificate Pinning inaktiveras för felsökning?

Ja, genom villkorlig kompilering: i debug-bygge är pinning inaktiverat, i release — aktiverat. Använd BuildConfig.DEBUG på Android eller #if DEBUG på iOS för växling. Gör aldrig detta via en runtime-flagga som är tillgänglig för användaren.

Vad göra om certifikatet har komprometterats?

Släpp omedelbart en app-uppdatering med nya avtryck och publicera den i butikerna. Använd en mekanism för tvångsuppdatering. Om reservpins inkluderade avtrycket av reserv-CA, kan man tillfälligt byta till en annan domän med ett annat certifikat.

Sammanfattning

  • Certificate Pinning — fixering av ett betrott certifikat eller dess offentliga nyckel för skydd mot MITM-attacker via falska CA
  • Två angreppssätt — certificate pinning (strikt, till certifikat) och public key pinning (flexibelt, till offentlig nyckel)
  • Reservpins obligatoriska — minst 2 avtryck för att säkerställa kontinuitet vid certifikatrotation
  • OkHttp CertificatePinner — standardimplementeringsmetod på Android med stöd för flera pins
  • URLSessionDelegate — primär metod på iOS med manuell verifiering av SecTrust och SHA-256-hashar
  • Misstag — avsaknad av reservpins, lagring utan obfuskering, förväxling av debug/release-konfigurationer
  • Rekommendation — använd public key pinning för de flesta projekt och Certificate Pinning endast för kritiska system

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också