Certificate Pinning, uygulamanın HTTPS bağlantısını doğrulamak için önceden bilinen bir parmak izi kullandığı, sunucu sertifikasını veya açık anahtarını sabitleme mekanizmasıdır. Bir CA üzerinden standart güven zincirinin aksine, pinning, tehlikeye girmiş bir sertifika yetkilisinin bile alan adınız için sahte sertifika düzenleyememesini garanti eder. OWASP MSTG (2025)'ye göre, Certificate Pinning, L2 koruma seviyesindeki uygulamalar için zorunlu kontroller listesinde yer almaktadır. Uygulama, kodda sertifika hash'lerinin saklanmasını ve her istekte doğrulamayı içerir.
Anahtar Noktalar
Certificate Pinning, bir uygulamanın güvenilir bir sertifikanın parmak izini sakladığı ve HTTPS bağlantısı kurmak için bunu tek kriter olarak kullandığı bir güvenlik tekniğidir. Standart TLS modelinde, istemci sunucu sertifikasının güvenilir bir kök CA tarafından imzalandığını doğrular — sistemde önceden yüklü yüzlerce sertifika yetkilisinden herhangi biri. Certificate Pinning bu zinciri doğrudan bir kontrole dönüştürür: sertifika, saklanan örnekle eşleşmeli veya beklenen açık anahtarı içermelidir.
Standart modelin sorunu, CA ihlali olaylarından sonra belirgin hale geldi — DigiNotar (2011), Comodo (2011), TrustCor (2022). Bir CA, alan adınız için sahte bir sertifika düzenlerse, tarayıcı veya uygulama bunu geçerli olarak kabul eder. Certificate Pinning bu saldırıyı önler: mükemmel imzalanmış sahte bir sertifika bile, parmak izi uygulamada sabitlenenle eşleşmediği için reddedilecektir.
Pinning terimi, pin — “iğne” veya “sabitleyici” — kelimesinden gelir: geliştirici güvenilir bir sertifikayı sabitler ve bundan herhangi bir sapma bağlantıyı engeller. Mitre CWE-295 araştırmasına göre, uygun olmayan sertifika doğrulaması, mobil uygulamalardaki en tehlikeli ilk 10 güvenlik hatası arasında yer almaya devam etmektedir ve Certificate Pinning bunu önlemenin doğrudan bir yöntemidir.
Başlangıçta, Certificate Pinning, RFC 7469'da standartlaştırılan HPKP (HTTP Public Key Pinning) mekanizması aracılığıyla tarayıcılarda kullanılıyordu. Geliştirici, beklenen anahtarların hash'lerini içeren bir HTTP Public-Key-Pins başlığı gönderir ve tarayıcı bunları belirtilen bir süre boyunca saklardı. Ancak HPKP tehlikeli olduğu ortaya çıktı: tek bir yapılandırma hatası bir siteyi aylarca engelleyebilirdi. 2018'de Chrome, HPKP desteğini sonlandırdı ve mevcut standart istemci tarafı uygulama — bir mobil uygulama veya tarayıcı uzantısı içinde — haline geldi.
Certificate Pinning süreci üç temel aşamayı içerir: parmak izi hesaplama, bağlantı doğrulama ve hata yönetimi. Hazırlık aşamasında, geliştirici üretim sunucusunun sertifikasının veya açık anahtarının SHA-256 hash'ini alır. GDPR ve PCI DSS uyumlu uygulamalar için, zincirdeki ara CAların parmak izlerini de sabitlemek gerekir.
Her HTTPS isteğinde, uygulama TLS kimlik doğrulama geri çağrımını yakalar, sunucunun sertifikasını çıkarır ve SHA-256 hash'ini hesaplar. Bu hash, saklanan güvenilir parmak izleri listesiyle karşılaştırılır. Bir eşleşme bulunursa — bağlantı devam eder. Bulunmazsa — uygulama bağlantıyı sonlandırmalı ve saldırgana uygulama ayrıntılarını ifşa etmeden hatayı bildirmelidir.
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
}
Fonksiyon, sunucudan bir X509Certificate nesnesi ve beklenen hash'i alır. Önce sertifikanın açık anahtarını çıkarır, SHA-256 hash'ini hesaplar ve Base64'e kodlar. Sonuç, beklenen parmak izi ile karşılaştırılır. Üretimde, rotasyonu desteklemek için 2–3 parmak izinden oluşan bir diziye karşı doğrulama eklemek gerekir.
Pinning uygularken, hangi kriptografik nesnenin sabitleneceğini seçmek gerekir. Certificate Pinning, X.509 sertifikasının kendisine — seri numarasına, geçerlilik süresine ve tüm zincire — bağlanır. Public Key Pinning, sertifika içindeki yalnızca açık anahtarı sabitler, diğer alanları görmezden gelir. Bu seçim, işletme maliyetlerini önemli ölçüde etkiler.
| Kriter | Certificate Pinning | Public Key Pinning |
|---|---|---|
| Sabitleme nesnesi | Tam X.509 sertifikası | RSA/ECDSA açık anahtarı |
| Rotasyon | Her yeniden düzenlemede güncelleme gerektirir | Aynı anahtarla sertifika yenilemede değişmez |
| Güvenlik | Maksimum hassasiyetli bağlama | Ayrıntılara karşı daha az hassas |
| Esneklik | Düşük — sertifikalar her 1–2 yılda bir değişir | Yüksek — anahtarlar 5–10 yıl dayanabilir |
| Öneri | Kontrollü güncellemeli kritik sistemler için | Çoğu mobil uygulama ve API için |
Public Key Pinning çoğu proje için tercih edilen seçimdir. Sertifika yeniden düzenlenirken sunucuların açık anahtarları genellikle değişmez — şirket eski anahtarı yeni bir sertifikayla imzalar. Bu, anahtar çifti değişmemişse, sertifika değişikliğinden sonra uygulamanın güncelleme gerektirmediği anlamına gelir. Öte yandan Certificate Pinning, geliştiricinin hem sunucuyu hem de istemci kodunu tamamen kontrol ettiği senaryolarda — örneğin sıkı güncelleme döngüsüne sahip kurumsal uygulamalarda — önerilir.
TOFU, Certificate Pinning'in önceden yapılandırılmadığı, bunun yerine sunucuya ilk bağlantıda sertifikayı hatırladığı bir stratejidir. Bu yaklaşım, önceden hangi sunucuya bağlanacağını bilmeyen uygulamalar için uygundur. Dezavantajı, ilk saldırıya karşı savunmasızlıktır: ilk bağlantı ele geçirilirse, sahte bir sertifika güvenilir olarak kabul edilecektir. TOFU, SSH bağlantılarında ve bazı P2P protokollerinde kullanılır.
Her iki platformda da Certificate Pinning, ağ yığı seviyesinde TLS bağlantısını yakalayarak uygulanır. iOS'ta URLSession delegesi veya Alamofire ServerTrustManager kullanılır. Android'de tercih edilen yöntem, popüler HTTP istemcilerine yerleşik olan ve her alan adı için birden çok parmak izi yapılandırmasını destekleyen OkHttp CertificatePinner'dır.
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 fonksiyonunda, serverTrust'tan sertifika zinciri çıkarılır, her sertifika için SHA-256 hash'i hesaplanır ve sonuç beklenenle karşılaştırılır. Zincirdeki tüm sertifikalar arasında gezinmek, ara CA seviyesinde pinning uygulamaya olanak tanır — bir ara sertifika eşleşirse bağlantı kabul edilir. Bu, yaprak sertifika rotasyonu sırasında esneklik sağlar.
Uygulama OkHttp kullanmıyorsa, Certificate Pinning özel bir X509TrustManager aracılığıyla uygulanabilir. Bu yöntem daha fazla kod gerektirir ancak doğrulama süreci üzerinde tam kontrol sağlar. TrustManager, geliştiricinin sunucu sertifikalarını manuel olarak doğruladığı ve güvenip güvenmeyeceğine karar verdiği checkServerTrusted yöntemini geçersiz kılar. Yalnızca OkHttp kütüphanesinin mevcut olmadığı belirli senaryolarda önerilir.
En yaygın hata, yedek pinlerin olmamasıdır. Geliştirici tek bir sertifika parmak izi ekler ve süresi dolduğunda kullanıcılar toplu halde bağlantıyı kaybeder. Kabul edilebilir minimum yapılandırma iki parmak izidir: mevcut sertifika ve bir yedek. İdeal olarak üç: mevcut, bir yedek ve yedek olarak kök CA parmak izi.
İkinci hata, pinlerin kodda düz metin olarak saklanmasıdır. APK veya IPA'ya erişimi olan bir saldırgan, parmak izlerini kolayca çıkarıp değiştirebilir. Hash karartma önerilir: dizeyi parçalara ayırın, şifrelenmiş kaynaklarda saklayın veya çalışma zamanında hesaplayın. Android için, dize sabiti karartma ile ProGuard etkilidir.
Üçüncü hata, geliştirme sertifikası seviyesinde pinning yapmaktır. Geliştirme ve üretim sertifikaları genellikle farklıdır, ancak geliştiriciler genellikle bir sürüm derlerken pinleri değiştirmeyi unutur. Sonuç olarak, üretim uygulaması sunucuya bağlanamaz. Çözüm, BuildConfig veya flavor'a özgü kaynaklar aracılığıyla hata ayıklama ve sürüm için ayrı pin yapılandırmalarıdır.
Sıkça Sorulan Sorular
SSL Pinning, bir SSL/TLS sertifikasına bağlanmak için genel bir terimdir. Certificate Pinning, yalnızca açık anahtarı değil, X.509 sertifikasının kendisini sabitleyen özel bir uygulamadır. Fark, bağlama nesnesindedir: sertifika vs anahtar.
ProGuard (Android) ile karartma işlemi uygulanmış kaynaklarda veya Keychain (iOS) aracılığıyla şifrelenmiş olarak hash'lerin saklanması önerilir. Şifreleme olmadan strings.xml veya Info.plist'te pinleri düz metin olarak saklamaktan kaçının.
Sunucudaki her sertifika değişikliğinde. Mevcut sertifikanın süresinin dolmasından 3–6 ay önce yeni bir parmak izini yedek pin olarak eklemeniz ve rotasyondan sonra eskisini kaldırmanız önerilir. En az bir yedek pin zorunludur.
Evet, koşullu derleme yoluyla: hata ayıklama yapısında pinning devre dışı, sürüm yapısında etkindir. Geçiş için Android'de BuildConfig.DEBUG veya iOS'ta #if DEBUG kullanın. Bunu asla kullanıcının erişebileceği bir çalışma zamanı bayrağıyla yapmayın.
Derhal yeni parmak izleriyle bir uygulama güncellemesi yayınlayın ve mağazalarda yayımlayın. Zorunlu güncelleme mekanizması kullanın. Yedek pinler yedek CA parmak izini içeriyorsa, geçici olarak farklı bir sertifikaya sahip başka bir alan adına geçebilirsiniz.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun