SSL Pinning — تکنیک امنیتی است که در آن اپلیکیشن گواهی سرور را بر اساس اثرانگشت یا گواهی از پیش شناختهشده بررسی میکند، نه اینکه به زنجیره اعتماد CA متکی باشد. برخلاف بررسی استاندارد، پینینگ از رهگیری ترافیک از طریق مراکز ریشه جعلی گواهی جلوگیری میکند. طبق OWASP Mobile Security Testing Guide (2025)، این تکنیک در فهرست سه کنترل برتر برای محافظت در برابر حملات MITM قرار دارد. بدون پینینگ، مهاجم با گواهی ریشه جعلی میتواند تمام ترافیک HTTPS اپلیکیشن را رمزگشایی کند.
نکات اصلی
SSL Pinning — مکانیزم امنیتی است که در آن اپلیکیشن موبایل یا وب، گواهی یا کلید عمومی مورد اعتماد سرور را به خاطر میسپارد و هر اتصالی را که گواهیاش با ذخیرهشده مطابقت نداشته باشد رد میکند. در طرح استاندارد HTTPS، کلاینت گواهی را از طریق زنجیره اعتماد تا CA ریشه بررسی میکند — هر CA میتواند برای هر دامنهای گواهی امضا کند. SSL Pinning این نقطه ضعف را برطرف میکند: به جای اعتماد به صدها CA، اپلیکیشن فقط به یک گواهی خاص اعتماد میکند.
مشکل بررسی استاندارد این است که هر یک از صدها CA ریشه میتواند یک گواهی معتبر برای دامنه شما صادر کند — تصادفی یا تحت اجبار. مهاجمی که به پروکسی شرکتی با گواهی ریشه خودش دسترسی پیدا کند، میتواند حمله MITM را بدون هشدار مرورگر انجام دهد. SSL Pinning این آسیبپذیری را میبندد: حتی اگر CA گواهی جعلی صادر کند، اپلیکیشن آن را رد میکند، زیرا اثرانگشت با ثبتشده مطابقت ندارد.
در اپلیکیشنهای موبایل، SSL Pinning به ویژه مهم است زیرا دستگاهها اغلب در شبکههای ناامن کار میکنند — Wi-Fi عمومی، پروکسیهای شرکتی با بازرسی ترافیک، نقاط دسترسی آلوده. طبق Verizon Mobile Security Index (2025)، بیش از 60% نشت دادهها در اپلیکیشنهای موبایل به رهگیری ترافیک در سطح حملونقل مرتبط است.
اپلیکیشنهای موبایل دادههای حساسی را منتقل میکنند — توکنهای احراز هویت، اطلاعات پرداخت، دادههای شخصی کاربران. بدون محافظت اضافی، HTTPS میتواند از طریق جایگزینی گواهی ریشه در دستگاه به خطر بیفتد — مثلاً پس از نصب پروفایل شرکتی یا اپلیکیشن مخرب. SSL Pinning تضمین میکند که حتی اگر CA ریشه جعلی روی دستگاه نصب شده باشد، اپلیکیشن به بررسی گواهی بر اساس لیست سفید خود ادامه میدهد.
فرآیند SSL Pinning از سه مرحله تشکیل شده است: دریافت اثرانگشت، بررسی در زمان اتصال و مدیریت خطا. در مرحله توسعه، مهندس اثرانگشت SHA-256 گواهی سرور را دریافت میکند (openssl x509 -fingerprint -sha256) و آن را در کد اپلیکیشن یا فایل پیکربندی قرار میدهد. در هر درخواست HTTPS، اپلیکیشن اثرانگشت گواهی دریافتی را محاسبه کرده و با ذخیرهشده مقایسه میکند — اگر مقادیر مطابقت نداشته باشند، اتصال قطع میشود.
مرحله اول — پینینگ در مرحله ساخت: توسعهدهنده از قبل گواهیهای سرور را میداند و هشهای آنها را جاسازی میکند. مرحله دوم — پینینگ در اولین اتصال (trust on first use, TOFU): اپلیکیشن گواهی را در اولین درخواست ذخیره میکند و از آن برای بررسی تمام درخواستهای بعدی استفاده میکند. TOFU برای محیطهای پویا مناسب است، اما در اولین حمله آسیبپذیر است — اگر اولین اتصال قبلاً رهگیری شده باشد، گواهی جعلی به عنوان معتبر پذیرفته میشود.
جزئیات بحرانی — اثرانگشتهای پشتیبان (backup pins). گواهیها تاریخ انقضا دارند و هنگام تعویض آنها، اپلیکیشن بهروزرسانینشده اتصال به سرور را از دست میدهد. مهندسان 2–3 اثرانگشت اضافی اضافه میکنند — مثلاً اثرانگشت گواهی پشتیبان و اثرانگشت CA ریشه. اگر گواهی اصلی تغییر کند، اپلیکیشن بر اساس backup pins بررسی میکند و اتصال ادامه مییابد.
# دریافت اثرانگشت SHA-256 گواهی
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
دو رویکرد اصلی برای پیادهسازی پینینگ وجود دارد: اتصال به کل گواهی (certificate pinning) و اتصال به کلید عمومی (public key pinning). هر رویکرد نقاط قوت و محدودیتهای خود را دارد که بر امنیت و سهولت نگهداری تأثیر میگذارد.
| نوع | شیء تثبیت | انعطافپذیری | امنیت |
|---|---|---|---|
| Certificate Pinning | کل گواهی X.509 | کم — با تغییر گواهی نیاز به بهروزرسانی است | بالا — اتصال دقیق |
| Public Key Pinning | کلید عمومی گواهی | متوسط — کلید میتواند در گواهی جدید باشد | بالا — کمتر به جزئیات گواهی حساس است |
| Hash Pinning | هش SHA-256 گواهی یا کلید | بالا — میتوان گواهیها را بدون تغییر کلید عوض کرد | متوسط — به مقاومت هش بستگی دارد |
اتصال به گواهی — سختگیرانهترین روش. اپلیکیشن کپی گواهی مورد اعتماد یا اثرانگشت SHA-256 آن را ذخیره میکند و در هر اتصال HTTPS با گواهی سرور مقایسه میکند. این روش حداکثر امنیت را فراهم میکند، اما در چرخش مشکل ایجاد میکند — گواهیها معمولاً 1–2 سال اعتبار دارند و پس از آن نیاز به بهروزرسانی اجباری اپلیکیشن است. برای سیستمهای حیاتی با چرخه بهروزرسانی کنترلشده توصیه میشود.
تثبیت کلید عمومی — رویکردی انعطافپذیرتر. به جای کل گواهی، اپلیکیشن فقط کلید عمومی RSA یا ECDSA سرور را ذخیره میکند. کلید میتواند در هنگام صدور مجدد گواهی بدون تغییر باقی بماند، اگر شرکت از همان جفت کلید استفاده کند. این کار تعداد بهروزرسانیهای اپلیکیشن را کاهش میدهد. با این حال، اگر کلید به خطر بیفتد، نیاز به تعویض آبشاری در همه کلاینتها خواهد بود.
در پلتفرم Apple، SSL Pinning از طریق نماینده URLSession پیادهسازی میشود. توسعهدهنده کلاسی ایجاد میکند که پروتکل URLSessionDelegate را پیادهسازی کرده و متد didReceive challenge را بازنویسی میکند، جایی که به صورت دستی گواهی سرور را با اثرانگشتهای ذخیرهشده مقایسه میکند. رویکرد جایگزین — استفاده از Alamofire با ServerTrustManager که پیکربندی را ساده میکند.
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)
}
}
}
در مثال، نماینده درخواست احراز هویت را از URLSession دریافت میکند، serverTrust را از challenge استخراج کرده و اثرانگشت SHA-256 گواهی را با ذخیرهشده مقایسه میکند. اگر اثرانگشت مطابقت داشت — اتصال ادامه مییابد، در غیر این صورت challenge رد میشود. برای محیط تولید، اضافه کردن بررسی چندین backup pins و ثبت خطاها برای نظارت توصیه میشود.
از iOS 14 به بعد، Apple پشتیبانی داخلی برای Certificate Pinning از طریق Info.plist اضافه کرد. توسعهدهنده گواهیهای مورد اعتماد را در کلید NSAppTransportSecurity با زیرفرهنگ NSPinnedDomains مشخص میکند. این رویکرد نیازی به نوشتن کد ندارد، اما انعطافپذیری کمتری دارد — نمیتوان پینها را به صورت پویا تغییر داد یا خطاهای بررسی را ثبت کرد.
در Android سه روش اصلی برای پیادهسازی SSL Pinning وجود دارد: از طریق CertificatePinner کتابخانه OkHttp، از طریق Network Security Config در XML و از طریق بررسی سفارشی در HttpsURLConnection. OkHttp — محبوبترین و توصیهشدهترین رویکرد است که در Retrofit و سایر کلاینتهای HTTP استفاده میشود.
val certificatePinner = CertificatePinner.Builder()
.add("api.example.com",
"sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=")
.add("api.example.com",
"sha256/FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=") // پین پشتیبان
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
در پیکربندی OkHttp، توسعهدهنده دامنه و یک یا چند اثرانگشت SHA-256 را مشخص میکند. در اولین اثرانگشت، OkHttp گواهی سرور را با پینهای مشخصشده مقایسه میکند. اگر مطابقت نداشته باشد، کلاینت SSLPeerUnverifiedException را پرتاب میکند. پین پشتیبان اجباری است — بدون آن، با تغییر گواهی، درخواستهای API بلافاصله شروع به شکست میکنند.
Android از API 24 به بعد از Certificate Pinning اعلامی از طریق پیکربندی XML پشتیبانی میکند. فایل res/xml/network_security_config.xml شامل لیست دامنهها و اثرانگشتهای آنها است. این روش برای پیکربندیهای ایستا مناسب است، اما اجازه پیادهسازی TOFU یا منطق بررسی سفارشی با ثبت ناهنجاریها را نمیدهد.
<!-- 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 امنیت اپلیکیشن موبایل را به طور قابل توجهی افزایش میدهد، اما پیچیدگی عملیاتی ایجاد میکند. مزیت اصلی — محافظت در برابر حملات MITM حتی در صورت به خطر افتادن CAهای ریشه. اپلیکیشن فقط به گواهیهایی اعتماد میکند که به صراحت توسط توسعهدهنده مشخص شدهاند، نه به کل زیرساخت مراکز گواهی عمومی. این به ویژه برای اپلیکیشنهای مالی، پیامرسانها و اپلیکیشنهای با دادههای حساس حیاتی است.
عیب اصلی — پیچیدگی چرخش گواهیها. اگر گواهی منقضی یا ابطال شود، کاربرانی که اپلیکیشن را بهروزرسانی نکردهاند اتصال را از دست میدهند. این مشکل از طریق پینهای پشتیبان و مکانیزم بهروزرسانی تدریجی حل میشود: اپلیکیشن جدید گواهی قدیمی و جدید را میشناسد و پس از بهروزرسانی کامل کاربران، پین قدیمی از کد حذف میشود. توصیه میشود حداقل 2 پین پشتیبان قرار دهید — یکی برای گواهی فعلی، یکی برای آینده.
سازش دیگر — عدم امکان استفاده از پروکسیهای عمومی برای اشکالزدایی ترافیک (Charles Proxy, Burp Suite) بدون غیرفعال کردن پینینگ. این کار اشکالزدایی درخواستهای شبکه را در مرحله توسعه دشوار میکند. راهحل — کامپایل شرطی: در بیلد دیباگ پینینگ غیرفعال است، در بیلد ریلیز فعال است. OWASP استفاده از پرچم BuildConfig.DEBUG را برای تغییر توصیه میکند.
| جنبه | مزیت | عیب |
|---|---|---|
| امنیت | محافظت در برابر MITM از طریق CAهای جعلی | پیچیدگی در به خطر افتادن کلید |
| نگهداری | کنترل صریح اعتماد | چرخش نیاز به بهروزرسانی اپلیکیشن دارد |
| اشکالزدایی | تضمین اتصال به سرور صحیح | مسدودسازی پروکسیهای اشکالزدایی |
سوالات متداول
بررسی استاندارد HTTPS به هر گواهی امضا شده توسط یک CA ریشه شناخته شده اعتماد میکند. SSL Pinning فقط به گواهی یا کلید خاص اعتماد میکند — اگر CA گواهی جعلی صادر کند، اپلیکیشن آن را رد میکند.
گواهیها معمولاً 1–2 سال اعتبار دارند. توصیه میشود پینها را 3–6 ماه قبل از انقضای گواهی فعلی بهروزرسانی کنید، اثرانگشت جدید را به عنوان پین پشتیبان اضافه کرده و پس از چرخش، قدیمی را حذف کنید.
بله، اما باید در نظر داشت که CDN ممکن است هنگام جابجایی بین سرورهای لبه، گواهیها را تغییر دهد. توصیه میشود به کلید عمومی متصل شوید، نه به گواهی خاص، و از چندین پین پشتیبان استفاده کنید.
اتصال با خطا قطع میشود — در Android این SSLPeerUnverifiedException است، در iOS challenge با .cancelAuthenticationChallenge رد میشود. اپلیکیشن باید این خطا را به درستی مدیریت کرده و به کاربر اطلاع دهد.
خیر، اما OWASP آن را برای اپلیکیشنهایی که با دادههای حساس کار میکنند توصیه میکند: بانکی، پزشکی، سیستمهای شرکتی. برای اپلیکیشنهای ساده read-only، بررسی استاندارد HTTPS با گواهیهای EV معمولاً کافی است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید