Certificate Pinning (закрепване на сертификат) — това е техника за сигурност, при която мобилното приложение проверява дали сертификатът на сървъра съвпада с предварително известен образец, а не просто се доверява на произволен сертификат от веригата CA. За разлика от обикновената TLS проверка, която разчита на стотици сертификационни центрове, pinning стеснява доверието до един конкретен сертификат или неговия публичен ключ. Според OWASP Mobile Security Testing Guide (2024), внедряването на Certificate Pinning затваря 100% от сценариите за Man-in-the-Middle атаки, свързани с подмяна на сертификат. OWASP MSTG, 2024
Основни точки
Certificate Pinning — това е механизъм за сигурност, при който приложението запазва (или „зашива" — pin) образец на сертификата на сървъра и при всяка връзка сравнява получения сертификат с този образец. Ако сертификатът не съвпада — връзката се прекъсва, дори ако е официално подписан от доверен сертификационен център. Това предпазва от атаки, при които нападателят получава фалшив сертификат чрез компрометиран CA (както се случи с DigiNotar през 2011 г. или Comodo през 2011 г.).
Процесът на pinning се състои от три етапа: извличане на отпечатък (fingerprint) на сертификата или публичния ключ от доверен екземпляр; съхраняване на този отпечатък в кода или ресурсите на приложението; сравнение на етапа TLS-handshake. Разработчикът може да фиксира SHA-256 отпечатъка на целия сертификат или само на публичния ключ (Public Key Pinning). Вторият подход е за предпочитане: при удължаване на сертификата публичният ключ често остава същият и приложението не губи връзка със сървъра. По препоръка на OWASP минималният брой пинове — 2: един текущ и един резервен за случай на ротация на ключове. Модерните библиотеки, като OkHttp и TrustKit, автоматизират процеса на проверка на посочените пинове при всяка TLS връзка без допълнителни усилия от разработчика. Важно е да се разбере, че pinning не замества стандартната TLS проверка, а я допълва: първо се извършва обичайното handshake с валидиране на веригата от сертификати, след това — допълнителна pinning проверка. Такава двустепенна защита елиминира уязвимостите, свързани с компрометиране на CA, включително случаи на грешно издаване на сертификати и атаки върху инфраструктурата на сертификационните центрове.
Съществуват няколко подхода за внедряване на Certificate Pinning, всеки със свои характеристики на съхранение и проверка. Изборът на метод зависи от архитектурата на приложението, честотата на актуализиране на сертификатите и изискванията за гъвкавост.
| Тип pinning | Какво се съхранява | Гъвкавост | Пример за употреба |
|---|---|---|---|
| Certificate Pinning | Целият сертификат X.509 | Ниска | Фиксиран сертификат за 1–2 години |
| Public Key Pinning | Публичен ключ (SPKI) | Средна | Препоръчван от OWASP подход |
| Hash Pinning | SHA-256 отпечатък | Средна | Популярен в OkHttp (certificatePinner) |
| CA Pinning | Междинен CA | Висока | Корпоративни приложения |
Най-балансираният метод е Public Key Pinning, препоръчан от OWASP и Google. Вместо конкретен сертификат (който се променя на всеки 1–2 години) приложението съхранява отпечатък SubjectPublicKeyInfo — абстракция на публичния ключ. Ако сертификатът се удължи със същия ключ (key reuse), pin остава валиден. Ако ключът се промени — разработчикът предварително добавя резервен pin в актуализацията на приложението. В мобилните проекти се използва стратегия min/max pins: минимум 2 пина, включително резервен, и максимум 4 за предотвратяване на нарастване и увеличаване на времето за проверка.
Изборът на конкретен тип pinning зависи от архитектурата и изискванията на приложението. За публични мобилни приложения, комуникиращи с REST API чрез един домейн, оптимален е Public Key Pinning с два пина чрез OkHttp или TrustKit. За корпоративни приложения със собствен сертификационен център е подходящ CA Pinning — не изисква актуализация при смяна на клиентски сертификати, тъй като доверието е обвързано с CA, а не с крайния сертификат. За IoT и вградени системи се препоръчва Certificate Pinning с фиксиране на целия сертификат: устройствата рядко се актуализират, така че контролът върху цялата верига на доверие е критичен. Мониторингът на датите на изтичане на пиновете — задължителна практика: настройте предупреждения 30, 14 и 7 дни преди изтичане на сертификата, за да успеете да пуснете актуализация на приложението с нови пинове, преди текущият сертификат да стане невалиден. За автоматизиране на пускането на актуализации с нови пинове се препоръчва използването на Firebase Remote Config или собствен API за конфигурация, който позволява динамично актуализиране на списъка с пинове без публикуване на нова версия в магазина за приложения.
Certificate Pinning значително повишава сигурността на мобилното приложение, но налага оперативно натоварване на екипа за разработка. Важно е да се претеглят ползите от защитата и риска от блокиране на връзката при неправилно внедряване.
Основното предимство — защита от Man-in-the-Middle атаки, включително случаи на компрометиране на CA. Pinning прави безполезни фалшивите сертификати, издадени от нападателя: дори ако CA е подписал фалшификат, приложението го отхвърля. Допълнителен плюс — защита от корпоративни прокси сървъри, които подменят сертификати за инспекция на трафика. Според Google Security Blog (2023), приложенията с pinning имат 86% по-малък шанс да бъдат хакнати чрез прихващане на трафик в сравнение с приложенията, използващи само стандартна TLS проверка.
Основният недостатък на pinning — риск от самоблокиране: ако сертификатът на сървъра се промени (удължаване, смяна на доставчик, ротация на ключове) преди излизане на актуализация на приложението, потребителите губят достъп до сървъра. Допълнителни минуси: трудност при отстраняване на грешки (при всяка промяна на настройките трябва да се актуализират пиновете), увеличение на размера на APK с 5–15 KB при използване на TrustKit и невъзможност за бързо връщане на промени без нова версия. За минимизиране на рисковете се използват резервни пинове, автоматична ротация на всеки 2–3 месеца и гратисен период (grace period), в който приложението приема както стария, така и новия сертификат. Също така трябва да се има предвид, че при разработка с включен pinning не могат да се използват прокси инструменти (Burp Suite, Charles) за отстраняване на грешки в мрежови заявки — за версии за разработка pinning трябва да бъде изключен чрез флага BuildConfig.DEBUG, а QA тестването трябва да се извършва върху подпис за издаване с включена защита. Някои екипи използват staging домейн с отделен pinning сертификат за среда за разработка, за да запазят защитата дори на етапа на разработка.
Нека разгледаме пример за внедряване на Certificate Pinning в Android с помощта на OkHttp — стандартната библиотека за мрежови заявки. OkHttp предоставя вграден CertificatePinner, който приема SHA-256 хешове на публични ключове.
val certificatePinner = CertificatePinner.Builder()
.add(
"api.example.com",
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
)
.add(
"api.example.com",
"sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB="
)
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
В кода по-горе добавяме два пина за домейна api.example.com: основен (текущ сертификат) и резервен (за случай на ротация). OkHttp автоматично проверява дали сертификатът на сървъра съвпада с един от посочените SHA-256 отпечатъци. За получаване на SHA-256 отпечатъка на сертификата се използва командата: openssl s_client -connect api.example.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64. Важно е да съхранявате отпечатъците не в отворен вид в кода, а криптирани или объркани: статичният анализ MobSF лесно намира голи SHA-256 низове в DEX файлове. Препоръчва се съхраняване на пинове в ресурси res/raw, криптирани чрез AES, и дешифрирането им при стартиране на приложението чрез роден код (NDK/JNI).
На iOS основният инструмент за Certificate Pinning е библиотеката с отворен код TrustKit. За разлика от OkHttp, TrustKit се конфигурира декларативно чрез Info.plist, което позволява промяна на пинове без прекомпилиране на приложението. Конфигурацията включва речник с домейни и масив от SHA-256 отпечатъци на публични ключове. TrustKit автоматично прихваща NSURLSession заявки и проверява сертификатите преди започване на прехвърлянето на данни. Ключова характеристика на TrustKit — поддръжка на доклади за валидиране на пинове: библиотеката може да изпраща доклади до посочен endpoint при несъвпадение на pin, което позволява бърза реакция на аномалии в сертификатите. Apple също предоставя роден механизъм NSPinnedDomains в Info.plist от iOS 14, но TrustKit остава предпочитаният избор поради по-гъвкава конфигурация, поддръжка на доклади и възможност за гореща смяна на пинове без актуализация на системата. TrustKit се интегрира с URLSession чрез делегата didReceiveChallenge, връщайки .performDefaultHandling при успешна проверка на pin и .cancelAuthenticationChallenge при несъвпадение. За мониторинг на докладите за валидиране на пинове се препоръчва конфигуриране на отделен endpoint, който анализира честотата на грешките: ако броят на докладите рязко се увеличи — това може да показва MitM атака или предстоящо изтичане на сертификат, изискващо незабавно актуализиране на пиновете.
Често задавани въпроси
Certificate Pinning — това е като запазване на отпечатък от пръст на приятел в телефона: запомняте как изглежда „правилният" сертификат на сървъра и не се доверявате на никой друг, дори ако някой представи документ от „официален" център.
Обикновеният HTTPS се доверява на всеки сертификат, подписан от всеки CA от стотици центрове. Certificate Pinning добавя проверка „отгоре": сертификатът трябва не само да е валиден, но конкретно този, който сте фиксирали в кода на приложението.
Препоръчва се съхраняване на 2–3 пина: текущ и резервен за новия сертификат. 1–2 месеца преди смяната на сертификата пуснете нова версия на приложението с добавен pin на бъдещия сертификат. След смяната старият pin се премахва от следващото издание.
Да, може. Pinning работи с всякакви сертификати, включително Let's Encrypt. Важно е да запомните, че безплатните сертификати имат кратък срок на валидност (3 месеца), така че стратегията с резервни пинове и автоматичната ротация стават задължителни.
За тестване на pinning използвайте Burp Suite или mitmproxy. Ако приложението с pinning е правилно конфигурирано, прокси инструментът няма да може да прихване трафика — връзката ще бъде прекъсната на етапа handshake. За интеграционни тестове използвайте MockWebServer от OkHttp.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също