Certificate Pinning هي آلية تثبيت شهادة الخادم أو مفتاحه العام، حيث يستخدم التطبيق بصمة معروفة مسبقاً للتحقق من اتصال HTTPS. على عكس سلسلة الثقة القياسية عبر CA، يضمن التثبيت أنه حتى مركز الشهادات المخترق لا يمكنه إصدار شهادة مزيفة لنطاقك. وفقاً لـ OWASP MSTG (2025)، يُدرج Certificate Pinning في قائمة الضوابط الإلزامية للتطبيقات ذات مستوى الحماية L2. يتضمن التطبيق تخزين تجزئات الشهادات في الكود والتحقق منها عند كل طلب.
النقاط الرئيسية
Certificate Pinning هي تقنية أمان يخزن فيها التطبيق البصمة الرقمية لشهادة موثوقة ويستخدمها كمعيار وحيد لإنشاء اتصال 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 يُستخدم في المتصفحات عبر آلية HPKP (HTTP Public Key Pinning)، الموحدة في RFC 7469. كان المطور يرسل رأس HTTP Public-Key-Pins مع تجزئات المفاتيح المتوقعة، ويخزنها المتصفح لفترة محددة. لكن HPKP تبين أنه خطير: خطأ تكوين واحد يمكن أن يحظر موقعاً لأشهر. في 2018، أوقف Chrome دعم HPKP، وأصبح المعيار الحالي هو التطبيق من جانب العميل — داخل تطبيق محمول أو إضافة متصفح.
تتضمن عملية Certificate Pinning ثلاث مراحل رئيسية: حساب البصمة، التحقق من الاتصال، ومعالجة الأخطاء. أثناء التحضير، يحصل المطور على تجزئة SHA-256 لشهادة خادم الإنتاج أو مفتاحه العام. للتطبيقات المتوافقة مع GDPR وPCI DSS، من الضروري أيضاً تثبيت بصمات الـ CAs الوسيطة في السلسلة.
مع كل طلب HTTPS، يعترض التطبيق استدعاء مصادقة TLS، ويستخرج شهادة الخادم، ويحسب تجزئة SHA-256 الخاصة بها. تُقارن هذه التجزئة بقائمة البصمات الموثوقة المخزنة. إذا تم العثور على تطابق — يستمر الاتصال. إذا لم يكن كذلك — يجب على التطبيق قطع الاتصال والإبلاغ عن الخطأ دون الكشف عن تفاصيل التطبيق للمهاجم.
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 بشهادة X.509 نفسها — رقمها التسلسلي، فترة صلاحيتها، والسلسلة بأكملها. يثبت Public Key Pinning فقط المفتاح العام داخل الشهادة، متجاهلاً الحقول الأخرى. يؤثر هذا الاختيار بشكل كبير على التكاليف التشغيلية.
| المعيار | Certificate Pinning | Public Key Pinning |
|---|---|---|
| كائن التثبيت | شهادة X.509 كاملة | المفتاح العام RSA/ECDSA |
| التدوير | يتطلب تحديثاً عند كل إعادة إصدار | لا يتغير عند تجديد الشهادة بنفس المفتاح |
| الأمان | ربط شديد الدقة | أقل حساسية للتفاصيل |
| المرونة | منخفضة — الشهادات تتغير كل 1–2 سنوات | عالية — المفاتيح يمكن أن تدوم 5–10 سنوات |
| التوصية | للأنظمة الحرجة ذات التحديثات الخاضعة للرقابة | لمعظم التطبيقات المحمولة و APIs |
Public Key Pinning هو الخيار المفضل لمعظم المشاريع. تبقى المفاتيح العامة للخوادم عادة دون تغيير عند إعادة إصدار الشهادة — تقوم الشركة ببساطة بتوقيع المفتاح القديم بشهادة جديدة. هذا يعني أن التطبيق لا يتطلب تحديثاً بعد تغيير الشهادة إذا لم يتغير زوج المفاتيح. من ناحية أخرى، يُوصى بـ Certificate Pinning للسيناريوهات حيث يتحكم المطور بالكامل في كل من الخادم وكود العميل، كما في تطبيقات المؤسسات ذات دورة التحديث الصارمة.
TOFU هي استراتيجية لا يتم فيها تكوين Certificate Pinning مسبقاً، بل يتذكر الشهادة عند أول اتصال بالخادم. هذا النهج مناسب للتطبيقات التي لا تعرف مسبقاً أي خادم ستتصل به. الجانب السلبي هو الضعف أمام الهجوم الأولي: إذا تم اعتراض أول اتصال، فسيتم قبول شهادة مزيفة كموثوقة. يُستخدم TOFU في اتصالات SSH وبعض بروتوكولات P2P.
على كلتا المنصتين، يتم تطبيق Certificate Pinning من خلال اعتراض اتصال TLS على مستوى مكدس الشبكة. على iOS، يُستخدم مفوض URLSession أو Alamofire ServerTrustManager. على Android، الطريقة المفضلة هي OkHttp CertificatePinner، المدمج في عملاء HTTP المشهورين ويدعم تكوين بصمات متعددة لكل نطاق.
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 لكل شهادة، ومقارنة النتيجة مع المتوقعة. المرور عبر جميع الشهادات في السلسلة يسمح بتطبيق التثبيت على مستوى CA الوسيطة — إذا تطابقت شهادة وسيطة، يتم قبول الاتصال. هذا يوفر مرونة أثناء تدوير الشهادات الطرفية.
إذا كان التطبيق لا يستخدم OkHttp، يمكن تطبيق Certificate Pinning من خلال X509TrustManager مخصص. تتطلب هذه الطريقة كوداً أكثر ولكنها توفر تحكماً كاملاً في عملية التحقق. يتجاوز TrustManager طريقة checkServerTrusted، حيث يتحقق المطور يدوياً من شهادات الخادم ويقرر ما إذا كان يثق بها. يُوصى بها فقط للسيناريوهات المحددة حيث تكون مكتبة OkHttp غير متاحة.
الخطأ الأكثر شيوعاً هو عدم وجود backup pins. يضع المطور بصمة واحدة للشهادة، وعند انتهاء صلاحيتها، يفقد المستخدمون الاتصال بشكل جماعي. الحد الأدنى المقبول للتكوين هو بصمتان: الشهادة الحالية وأخرى احتياطية. مثالياً ثلاث: الحالية، واحتياطية، وبصمة CA الجذرية كخيار احتياطي.
الخطأ الثاني هو تخزين pins في نص عادي في الكود. يمكن للمهاجم الذي لديه إمكانية الوصول إلى APK أو IPA استخراج البصمات واستبدالها بسهولة. يُوصى بتعتيم التجزئات: تقسيم السلسلة إلى أجزاء، تخزينها في موارد مشفرة أو حسابها في وقت التشغيل. لـ Android، ProGuard مع تعتيم ثوابت السلاسل فعّال.
الخطأ الثالث هو التثبيت على مستوى شهادة التطوير. تختلف شهادات التطوير والإنتاج عادةً، لكن المطورين ينسون غالباً تبديل pins عند بناء الإصدار النهائي. النتيجة هي أن تطبيق الإنتاج لا يمكنه الاتصال بالخادم. الحل هو تكوينات منفصلة للـ pins لبيئتي debug و release عبر BuildConfig أو موارد خاصة بنكهة التطبيق.
الأسئلة الشائعة
SSL Pinning هو مصطلح عام للربط بشهادة SSL/TLS. Certificate Pinning هو تطبيق محدد يثبت شهادة X.509 نفسها، وليس فقط المفتاح العام. الفرق في كائن الربط: الشهادة مقابل المفتاح.
يُوصى بتخزين التجزئات في موارد مع تعتيم عبر ProGuard (Android) أو مشفرة عبر Keychain (iOS). تجنب تخزين pins في نص عادي في strings.xml أو Info.plist دون تشفير.
مع كل تغيير للشهادة على الخادم. يُوصى بإضافة بصمة جديدة كـ backup pin 3–6 أشهر قبل انتهاء صلاحية الحالية، وإزالة القديمة بعد التدوير. على الأقل بصمة احتياطية واحدة إلزامية.
نعم، من خلال التجميع الشرطي: التثبيت معطل في build التصحيح ومفعل في build الإصدار. استخدم BuildConfig.DEBUG على Android أو #if DEBUG على iOS للتبديل. لا تفعل ذلك أبداً من خلال علامة وقت تشغيل متاحة للمستخدم.
أصدر فوراً تحديثاً للتطبيق ببصمات جديدة وانشره في المتاجر. استخدم آلية التحديث الإجباري. إذا كانت backup pins تتضمن بصمة CA الاحتياطية، يمكنك التبديل مؤقتاً إلى نطاق آخر بشهادة مختلفة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا