Certificate Pinning: какво е, механизъм и начини на фиксиране

Автор: IT Sectr Публикувано: 2026-03-09 Време за четене: 8 мин

Certificate Pinning — механизъм за фиксиране на сертификата или публичния ключ на сървъра, при който приложението използва предварително известен отпечатък за проверка на HTTPS връзката. За разлика от стандартната верига на доверие чрез CA, pinning гарантира, че дори компрометиран сертификационен орган не може да издаде фалшив сертификат за вашия домейн. Според OWASP MSTG (2025), Certificate Pinning е в списъка на задължителните контроли за приложения с ниво на защита L2. Имплементацията включва съхраняване на хешове на сертификати в кода и проверка при всяка заявка.

Основни точки

  • Certificate Pinning — техника, при която приложението се доверява само на сертификата с предварително известен отпечатък, игнорирайки цялата CA верига
  • Public Key Pinning — алтернатива, която фиксира само публичния ключ, опростявайки ротацията при смяна на сертификата
  • HPKP (HTTP Public Key Pinning) — остарял стандарт на ниво HTTP заглавки, не се препоръчва за нови проекти
  • Backup pins — резервни отпечатъци, осигуряващи непрекъснатост на връзката при смяна или изтичане на основния сертификат
  • Имплементация на iOS чрез SecTrustEvaluate, на Android чрез CertificatePinner в OkHttp или TrustManager

Какво е Certificate Pinning?

Certificate Pinning — техника за сигурност, при която приложението съхранява отпечатъка (fingerprint) на доверен сертификат и го използва като единствен критерий за установяване на HTTPS връзка. В стандартния TLS модел клиентът проверява дали сертификатът на сървъра е подписан от доверен коренов CA — който и да е от стотиците предварително инсталирани органи в системата. Certificate Pinning заменя тази верига с директна проверка: сертификатът трябва да съвпада със съхранения образец или да съдържа очаквания публичен ключ.

Проблемът на стандартния модел стана очевиден след инцидентите с компрометиране на CA — DigiNotar (2011), Comodo (2011), TrustCor (2022). Ако CA издаде фалшив сертификат за вашия домейн, браузърът или приложението го приема като валиден. Certificate Pinning предотвратява тази атака: дори перфектно подписан фалшив сертификат ще бъде отхвърлен, тъй като отпечатъкът му не съвпада с фиксирания в приложението.

Терминът pinning произлиза от pin — „щифт“ или „фиксатор“: разработчикът фиксира доверения сертификат и всяко отклонение от него блокира връзката. Според изследване на Mitre CWE-295, неправилната валидация на сертификати остава една от топ-10 най-опасните грешки в сигурността на мобилни приложения, а Certificate Pinning е директният метод за предотвратяването ѝ.

История и еволюция на Certificate Pinning

Първоначално Certificate Pinning се използваше в браузъри чрез механизма HPKP (HTTP Public Key Pinning), стандартизиран в RFC 7469. Разработчикът изпращаше HTTP заглавка Public-Key-Pins с хешове на очаквани ключове, а браузърът ги запомняше за определен период. HPKP обаче се оказа опасен: една грешка в конфигурацията можеше да блокира сайта за месеци. През 2018 г. Chrome прекрати поддръжката на HPKP и сега стандартът е програмна имплементация от страна на клиента — вътре в мобилното приложение или разширението на браузъра.

Как работи Certificate Pinning?

Процесът на Certificate Pinning включва три ключови етапа: изчисляване на отпечатъка, проверка при свързване и обработка на грешка. В етапа на подготовка разработчикът получава SHA-256 хеш на сертификата или публичния ключ на продукционния сървър. За приложения, съвместими с GDPR и PCI DSS, се изисква също фиксиране на отпечатъците на междинните CA във веригата.

При всяка HTTPS заявка приложението прихваща callback за удостоверяване TLS, извлича сертификата на сървъра и изчислява неговия SHA-256 хеш. Този хеш се сравнява със съхранения списък от доверени отпечатъци. Ако се намери съвпадение — връзката продължава. Ако не — приложението трябва да прекъсне връзката и да отчете грешката, без да разкрива детайли по имплементацията на атакуващия.

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
}

Функцията приема X509Certificate обект от сървъра и очаквания хеш. Първо се извлича публичният ключ на сертификата, изчислява се SHA-256 хеш и се кодира в Base64. Резултатът се сравнява с очаквания отпечатък. В продукция си струва да се добави проверка по масив от 2–3 отпечатъка за поддръжка на ротация.

Certificate Pinning срещу Public Key Pinning

При имплементация на pinning трябва да се избере кой криптографски обект да се фиксира. Certificate Pinning се свързва със самия X.509 сертификат — неговия сериен номер, период на валидност и цялата верига. Public Key Pinning фиксира само публичния ключ вътре в сертификата, игнорирайки останалите полета. Изборът значително влияе върху оперативните разходи.

КритерийCertificate PinningPublic Key Pinning
Обект на фиксиранеX.509 сертификат изцялоПубличен ключ RSA/ECDSA
РотацияИзисква актуализация при всяко преиздаванеНе се променя при смяна на сертификата със същия ключ
СигурностМаксимално прецизно свързванеПо-малко чувствителен към детайли
ГъвкавостНиска — сертификатите се сменят на 1–2 годиниВисока — ключовете могат да живеят 5–10 години
ПрепоръкаЗа критични системи с контролирани актуализацииЗа повечето мобилни приложения и API

Public Key Pinning — предпочитан избор за повечето проекти. Публичните ключове на сървърите обикновено остават непроменени при преиздаване на сертификата — компанията просто подписва стария ключ с нов сертификат. Това означава, че приложението не изисква актуализация след смяна на сертификата, ако двойката ключове не е променена. Certificate Pinning се препоръчва за сценарии, при които разработчикът контролира напълно както сървъра, така и клиентския код, например в корпоративни приложения със строг цикъл на актуализация.

Trust On First Use (TOFU)

TOFU — стратегия, при която Certificate Pinning не е конфигуриран предварително, а запомня сертификата при първата връзка със сървъра. Този подход е удобен за приложения, които не знаят предварително към кой сървър ще се свържат. Недостатък — уязвимост при първата атака: ако първата връзка бъде прихваната, фалшивият сертификат ще бъде приет за доверен. TOFU се прилага в SSH връзки и някои P2P протоколи.

Имплементация на iOS и Android

И на двете платформи Certificate Pinning се имплементира чрез прихващане на TLS връзката на ниво мрежов стек. На iOS се използва делегат на URLSession или Alamofire ServerTrustManager. На Android предпочитаният начин е OkHttp CertificatePinner, който е вграден в популярни HTTP клиенти и поддържа конфигурация на множество отпечатъци за всеки домейн.

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
}

В Swift функцията от serverTrust се извлича веригата от сертификати, за всеки се изчислява SHA-256 хеш и резултатът се сравнява с очаквания. Преминаването през всички сертификати във веригата позволява имплементация на pinning на ниво междинен CA — ако междинният сертификат съвпада, връзката се приема. Това дава гъвкавост при ротация на leaf сертификати.

TrustManager за Android (персонализиран)

Ако приложението не използва OkHttp, Certificate Pinning може да се имплементира чрез персонализиран X509TrustManager. Този метод изисква повече код, но дава пълен контрол върху процеса на проверка. TrustManager презаписва метода checkServerTrusted, където разработчикът ръчно проверява сертификатите на сървъра и взема решение за доверие. Препоръчва се само за специфични сценарии, при които библиотеката OkHttp не е налична.

Грешки при имплементация на Certificate Pinning

Най-честата грешка — липса на резервни пинове. Разработчикът поставя един отпечатък на сертификата и при неговото изтичане потребителите масово губят връзка. Минимално приемливата конфигурация — два отпечатъка: текущ сертификат и резервен. Оптимално — три: текущ, резервен и отпечатък на коренов CA като fallback.

Втора грешка — съхраняване на пинове в отворен вид в кода. Атакуващ с достъп до APK или IPA може лесно да извлече и замени отпечатъците. Препоръчва се объркване на хешове: разделяне на низа на части, съхраняване в криптирани ресурси или изчисляване чрез runtime. За Android е ефективен ProGuard с объркване на низови константи.

Трета грешка — pinning на ниво development сертификат. Разработчиците и продукционните сертификати обикновено са различни, но разработчиците често забравят да сменят пиновете при изграждане на release. Резултат — продукционното приложение не може да се свърже със сървъра. Решение — отделна конфигурация на пинове за debug и release чрез BuildConfig или специфични за flavour ресурси.

  • Ignoring certificate chain — проверка само на leaf сертификата без вземане предвид на междинните CA, което прекъсва връзката при ротация
  • Hardcoded dates — твърдо кодирани дати на изтичане на сертификати, които не се променят след актуализация
  • No monitoring — липса на предупреждения за грешки на Certificate Pinning, поради което проблемите се откриват само от потребители
  • TOFU без валидация — използване на Trust On First Use без допълнителна проверка, позволяващо на първата MITM атака да фиксира фалшив сертификат

Често задавани въпроси

С какво Certificate Pinning се различава от SSL Pinning?

SSL Pinning — общ термин за свързване към SSL/TLS сертификат. Certificate Pinning — конкретна имплементация, която фиксира самия X.509 сертификат, а не само публичния ключ. Разликата е в обекта на фиксиране: сертификат спрямо ключ.

Как безопасно да съхраняваме отпечатъците на сертификати в приложението?

Препоръчва се съхраняване на хешове в ресурси с объркване чрез ProGuard (Android) или криптирани чрез Keychain (iOS). Избягвайте съхраняване на пинове в отворен вид в strings.xml или Info.plist без криптиране.

Колко често трябва да се сменят фиксираните отпечатъци?

При всяка смяна на сертификата на сървъра. Препоръчва се добавяне на нов отпечатък като резервен pin 3–6 месеца преди изтичане на текущия, а след ротация премахване на стария. Минимум един резервен pin е задължителен.

Може ли Certificate Pinning да се изключи за отстраняване на грешки?

Да, чрез условна компилация: в debug сборката pinning е изключен, в release — включен. Използвайте BuildConfig.DEBUG на Android или #if DEBUG на iOS за превключване. Никога не правете това чрез runtime флаг, достъпен за потребителя.

Какво да правим, ако сертификатът е компрометиран?

Незабавно пуснете актуализация на приложението с нови отпечатъци и я публикувайте в магазините. Използвайте механизъм за принудителна актуализация. Ако резервните пинове включват отпечатък на резервен CA, временно можете да преминете към друг домейн с друг сертификат.

Резюме

  • Certificate Pinning — фиксиране на доверен сертификат или неговия публичен ключ за защита срещу MITM атаки чрез фалшиви CA
  • Два подхода — certificate pinning (строг, към сертификата) и public key pinning (гъвкав, към публичния ключ)
  • Резервните пинове са задължителни — минимум 2 отпечатъка за осигуряване на непрекъснатост при ротация на сертификати
  • OkHttp CertificatePinner — стандартен начин за имплементация на Android с поддръжка на множество пинове
  • URLSessionDelegate — основен начин на iOS с ръчна проверка на SecTrust и SHA-256 хешове
  • Грешки — липса на резервни пинове, съхраняване без объркване, объркване на debug/release конфигурации
  • Препоръка — използвайте public key pinning за повечето проекти и Certificate Pinning само за критични системи

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също