SSL Pinning — o tehnică de securitate prin care aplicația verifică certificatul serverului pe baza unei amprente sau a unui certificat cunoscut anterior, în loc să se bazeze pe lanțul de încredere CA. Spre deosebire de verificarea standard, pinning previne interceptarea traficului prin centrele rădăcină de certificare substituite. Conform OWASP Mobile Security Testing Guide (2025), această tehnică se află în top-3 controale recomandate pentru protecția împotriva atacurilor MITM. Fără pinning, un atacator cu un certificat rădăcină substituit poate decripta întregul trafic HTTPS al aplicației.
Principalele puncte
SSL Pinning — este un mecanism de securitate prin care aplicația mobilă sau web memorează un certificat de încredere sau cheia publică a serverului și respinge orice conexiune al cărei certificat nu se potrivește cu cel salvat. În schema standard HTTPS, clientul verifică certificatul prin lanțul de încredere până la CA rădăcină — orice CA poate semna un certificat pentru orice domeniu. SSL Pinning elimină acest punct slab: în loc să aibă încredere în sute de CA-uri, aplicația are încredere doar într-un singur certificat specific.
Problema verificării standard este că oricare dintre sutele de CA-uri rădăcină poate emite un certificat valid pentru domeniul dvs. — accidental sau sub constrângere. Un atacator care obține acces la un proxy corporativ cu propriul certificat rădăcină poate efectua un atac MITM fără avertismentul browserului. SSL Pinning închide această vulnerabilitate: chiar dacă CA emite un certificat fals, aplicația îl va respinge, deoarece amprenta nu se potrivește cu cea înregistrată.
În aplicațiile mobile, SSL Pinning este deosebit de important deoarece dispozitivele funcționează adesea în rețele nesecurizate — Wi-Fi public, proxy-uri corporative cu inspecție a traficului, puncte de acces infectate. Conform Verizon Mobile Security Index (2025), peste 60% din scurgerile de date în aplicațiile mobile sunt legate de interceptarea traficului la nivelul transportului.
Aplicațiile mobile transmit date sensibile — token-uri de autentificare, informații de plată, date personale ale utilizatorilor. Fără protecție suplimentară, HTTPS poate fi compromis prin substituirea certificatului rădăcină pe dispozitiv — de exemplu, după instalarea unui profil corporativ sau a unei aplicații malițioase. SSL Pinning garantează că, chiar dacă pe dispozitiv este instalat un CA rădăcină fals, aplicația va continua să verifice certificatul conform propriei liste albe.
Procesul SSL Pinning constă din trei etape: captarea amprentei, verificarea la conexiune și gestionarea erorii. În faza de dezvoltare, inginerul obține amprenta SHA-256 a certificatului serverului (openssl x509 -fingerprint -sha256) și o încorporează în codul aplicației sau în fișierul de configurare. La fiecare cerere HTTPS, aplicația calculează amprenta certificatului primit și o compară cu cea salvată — dacă valorile nu se potrivesc, conexiunea este întreruptă.
Prima etapă — pinning în faza de compilare: dezvoltatorul cunoaște dinainte certificatele serverului și încorporează hash-urile acestora. A doua etapă — pinning la prima conexiune (trust on first use, TOFU): aplicația memorează certificatul la prima cerere și îl folosește pentru verificarea tuturor cererilor ulterioare. TOFU este convenabil pentru medii dinamice, dar este vulnerabil la primul atac — dacă prima conexiune este deja interceptată, certificatul fals va fi acceptat ca fiind de încredere.
Detaliul critic — amprentele de rezervă (backup pins). Certificatele au o perioadă de valabilitate, iar la înlocuirea lor, aplicația neactualizată va pierde conexiunea cu serverul. Inginerii adaugă 2–3 amprente suplimentare — de exemplu, amprenta certificatului de rezervă și amprenta CA rădăcină. Dacă certificatul principal se schimbă, aplicația verifică după backup pins, iar conexiunea continuă să funcționeze.
# Obținerea amprentei SHA-256 a certificatului
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
openssl x509 -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64
Există două abordări principale pentru implementarea pinning: fixarea la întregul certificat (certificate pinning) și fixarea la cheia publică (public key pinning). Fiecare abordare are puncte forte și limitări care influențează securitatea și ușurința de întreținere.
| Tip | Obiect de fixare | Flexibilitate | Securitate |
|---|---|---|---|
| Certificate Pinning | Întreg certificatul X.509 | Scăzută — la schimbarea certificatului necesită actualizare | Ridicată — fixare precisă |
| Public Key Pinning | Cheia publică a certificatului | Medie — cheia poate fi în noul certificat | Ridicată — mai puțin sensibil la detaliile certificatului |
| Hash Pinning | Hash SHA-256 al certificatului sau cheii | Ridicată — se pot schimba certificatele fără schimbarea cheii | Medie — depinde de rezistența hash-ului |
Fixarea la certificat — cea mai strictă metodă. Aplicația stochează o copie a certificatului de încredere sau amprenta SHA-256 a acestuia și o compară cu certificatul serverului la fiecare conexiune HTTPS. Această metodă asigură securitate maximă, dar creează probleme la rotire — certificatele sunt de obicei valabile 1–2 ani, după care este necesară actualizarea forțată a aplicației. Recomandată pentru sisteme critice cu ciclu controlat de actualizare.
Fixarea cheii publice — o abordare mai flexibilă. În locul întregului certificat, aplicația memorează doar cheia publică RSA sau ECDSA a serverului. Cheia poate rămâne neschimbată la reemisiunea certificatului, dacă compania folosește aceeași pereche de chei. Aceasta reduce frecvența actualizărilor aplicației. Cu toate acestea, dacă cheia este compromisă, va fi necesară înlocuirea în cascadă la toți clienții.
Pe platforma Apple, SSL Pinning se implementează prin delegatul URLSession. Dezvoltatorul creează o clasă care implementează protocolul URLSessionDelegate și suprascrie metoda didReceive challenge, unde verifică manual certificatul serverului față de amprentele salvate. O abordare alternativă — utilizarea Alamofire cu ServerTrustManager, care simplifică configurarea.
class SSLPinningDelegate: NSObject, URLSessionDelegate {
let pinnedHash = "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg="
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust
else { return completionHandler(.cancelAuthenticationChallenge, nil) }
if validate(serverTrust, pinnedHash) {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
}
În exemplu, delegatul primește o cerere de autentificare de la URLSession, extrage serverTrust din challenge și compară amprenta SHA-256 a certificatului cu cea salvată. Dacă amprenta se potrivește — conexiunea continuă, în caz contrar challenge-ul este respins. Pentru producție, merită adăugată verificarea mai multor backup pins și înregistrarea erorilor pentru monitorizare.
Începând cu iOS 14, Apple a adăugat suport încorporat pentru Certificate Pinning prin Info.plist. Dezvoltatorul indică certificatele de încredere în cheia NSAppTransportSecurity cu sub-dicționarul NSPinnedDomains. Această abordare nu necesită scriere de cod, dar este mai puțin flexibilă — nu se pot schimba dinamic pins-urile sau înregistra erorile de verificare.
Pe Android există trei metode principale de implementare a SSL Pinning: prin CertificatePinner al bibliotecii OkHttp, prin Network Security Config în XML și prin verificare personalizată în HttpsURLConnection. OkHttp — cea mai populară și recomandată abordare, utilizată în Retrofit și alte clientele HTTP.
val certificatePinner = CertificatePinner.Builder()
.add("api.example.com",
"sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=")
.add("api.example.com",
"sha256/FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=") // pin de rezervă
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
În configurarea OkHttp, dezvoltatorul indică domeniul și una sau mai multe amprente SHA-256. La prima amprentă, OkHttp compară certificatul serverului cu pins-urile specificate. Dacă nu există potrivire, clientul aruncă SSLPeerUnverifiedException. Backup pin-ul este obligatoriu — fără el, la schimbarea certificatului, cererile API vor începe imediat să eșueze.
Android suportă Certificate Pinning declarativ prin configurare XML începând cu API 24. Fișierul res/xml/network_security_config.xml conține lista domeniilor și amprentelor acestora. Această metodă este convenabilă pentru configurații statice, dar nu permite implementarea TOFU sau a logicii personalizate de verificare cu înregistrarea anomaliiilor.
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-12-31">
<pin digest="SHA-256">
Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=</pin>
<pin digest="SHA-256">
FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=</pin>
</pin-set>
</domain-config>
</network-security-config>
SSL Pinning crește semnificativ securitatea aplicației mobile, dar introduce complexitate operațională. Principalul avantaj — protecția împotriva atacurilor MITM chiar și la compromiterea CA-urilor rădăcină. Aplicația are încredere doar în certificatele specificate explicit de dezvoltator, nu în întreaga infrastructură a centrelor publice de certificare. Acest lucru este deosebit de critic pentru aplicațiile financiare, mesagerii și aplicațiile cu date sensibile.
Principalul dezavantaj — complexitatea rotirii certificatelor. Dacă un certificat expiră sau este revocat, utilizatorii fără actualizarea aplicației pierd conexiunea. Se rezolvă prin backup pins și un mecanism de actualizare treptată: noua aplicație cunoaște certificatul vechi și cel nou, iar după actualizarea completă a utilizatorilor, pin-ul vechi este eliminat din cod. Se recomandă minimum 2 backup pins — unul pentru certificatul curent, unul pentru cel viitor.
Un alt compromis — imposibilitatea utilizării proxy-urilor publice pentru depanarea traficului (Charles Proxy, Burp Suite) fără dezactivarea pinning-ului. Acest lucru complică depanarea cererilor de rețea în faza de dezvoltare. Soluția — compilarea condiționată: în compilarea debug pinning-ul este dezactivat, în release — activat. OWASP recomandă utilizarea flag-ului BuildConfig.DEBUG pentru comutare.
| Aspect | Avantaj | Dezavantaj |
|---|---|---|
| Securitate | Protecție împotriva MITM prin CA-uri false | Complexitate la compromiterea cheii |
| Întreținere | Control explicit al încrederii | Rotirea necesită actualizarea aplicației |
| Depanare | Garantarea conexiunii cu serverul corect | Blocarea proxy-urilor de depanare |
Întrebări frecvente
Verificarea standard HTTPS are încredere în orice certificat semnat de un CA rădăcină cunoscut. SSL Pinning are încredere doar în certificatul sau cheia specifică — dacă CA emite un certificat fals, aplicația îl va respinge.
Certificatele sunt de obicei valabile 1–2 ani. Se recomandă actualizarea pins-urilor cu 3–6 luni înainte de expirarea certificatului curent, adăugând noua amprentă ca backup pin, iar după rotire eliminând-o pe cea veche.
Da, dar trebuie luat în considerare că CDN-ul poate schimba certificatele la comutarea între serverele edge. Se recomandă fixarea la cheia publică, nu la un certificat specific, și utilizarea mai multor backup pins.
Conexiunea este întreruptă cu o eroare — pe Android este SSLPeerUnverifiedException, pe iOS challenge-ul este respins cu .cancelAuthenticationChallenge. Aplicația trebuie să gestioneze corect această eroare și să notifice utilizatorul.
Nu, dar OWASP îl recomandă pentru aplicațiile care lucrează cu date sensibile: banking, medicină, sisteme corporative. Pentru aplicațiile simple read-only, verificarea standard HTTPS cu certificate EV este de obicei suficientă.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și