تخطَّ إلى المحتوى

التحقق السليم من التوقيع

Spec: RFC 5280, §6 Spec: RFC 6960 Spec: RFC 5652 Evidence: Test-backed

تعني عبارة “التوقيع صالح” عادةً أنّ شيئًا واحدًا فقط قد فُحِص: أنّ الحسابات الرياضية متطابقة. أمّا التحقق الصحيح فيفحص خمسة أمور مستقلة على الأقل، وقد يفشل أيٌّ منها بطريقة تجعل علامة الصحّ الخضراء بلا معنى. تعرض هذه الصفحة مجموعة الفحوص الكاملة، وتوضّح لماذا تُعَدّ الإجابة الجزئية إجابة خطيرة.

القيمة المنطقية المفردة هي أخطر مُخرَج في هذا الموضوع كله. فهي تدفع القارئ إلى معاملة “صالح” على أنّها تعني “جدير بالثقة”، مع أنّ “صالح” قد لا تعني إلا أنّ البايتات لم تُعدَّل — بمفتاح صادر عن شهادة انتهت صلاحيتها قبل ثلاث سنوات، وأُلغيت الشهر الماضي، ولا تتسلسل إلى أيّ جهة تعترف بها. كلّ واحد من هذه الأمور فحص منفصل. والبرمجية التي تُبلِّغ بقيمة منطقية واحدة تكون قد قرّرت بصمت أيّ الفحوص كان مُهِمًّا، وقرّرت ذلك نيابةً عنك. في سياق تنظيمي أو تعاقدي، لا تُعَدّ عبارة “الأداة قالت إنّه صالح” دفاعًا إذا كانت الأداة لم تتحقّق إلا من أبسط خاصية.

يُجيب التحقق الكامل عن خمسة أسئلة منفصلة. وهذه الأسئلة مستقلة — فاجتياز أحدها لا يقول شيئًا عن البقية:

  1. السلامة — هل ما زالت البايتات الموقَّعة تُنتِج عند التجزئة ما يغطّيه التوقيع؟ (أعِد حساب مُلخَّص نطاق البايتات، ثم قارِن.)
  2. الأصالة — هل يتحقّق التوقيع التشفيري مقابل المفتاح العام في شهادة التوقيع، فوق السمات الموقَّعة؟
  3. مسار الشهادة — هل تتسلسل تلك الشهادة إلى مرتكز ثقة اخترتَه أنت، مع صلاحية كلّ حلقة فيه؟
  4. الوقت — هل كانت الشهادة ضمن نافذة صلاحيتها في الوقت المعنيّ، وهل ذلك الوقت موثوق به لا مُدَّعى ذاتيًا؟
  5. الإلغاء — هل كانت الشهادة غير مُلغاة في ذلك الوقت، بأدلّة (⁨OCSP/CRL⁩) يمكنك الحصول عليها فعليًا أو كانت مضمَّنة في المستند؟

عبارة “صالح” التي لا تُجري الفحوص الخمسة كلها هي إجابة غير مكتملة تبدو كأنها إجابة مكتملة.

كيف يتعامل ⁨NextPDF⁩ مع الأمر

قسم بعنوان «كيف يتعامل ⁨NextPDF⁩ مع الأمر»

يتعامل ⁨NextPDF⁩ مع كلّ سؤال على أنّه منفصل ويجب الإجابة عنه صراحةً. لا يُختزَل أيّ سؤال أبدًا في علامة متفائلة واحدة، ولا يُتجاوَز بصمت لأنّ فحصًا ما كان غير مريح. يُفرَض هذا السلوك عبر الاختبارات. لهذا السبب وُسِمت هذه الصفحة بأنّها مدعومة بالاختبارات لا مدعومة بالمعايير: فالسلوك تُثبِّته مجموعة الاختبارات، لا مجرّد الاستدلال عليه من بند في معيار.

تُختبَر السلامة والأصالة من البداية إلى النهاية. تستخدم مجموعة الاختبارات شهادة معروفة لتوقيع بنية سمات موقَّعة حقيقية، ثم تتحقّق من التوقيع بالمفتاح العام المطابق عبر متجهات زمنية متعددة. وأيّ تغيير يُفسِد البنية المعيارية يُفشِل الاختبار. ويُثبِّت التحقق من مسار الشهادة اختباراتٌ تعبث عمدًا ببايت في التوقيع وتؤكّد أنّ النتيجة غير صالحة مع سبب مُنظَّم — لا استثناءً مُهمَلًا، بل فشلًا صريحًا مُسجَّلًا. يُجزَّأ التحقق من رمز الطابع الزمني إلى خطوات منفصلة — فكّ الترميز، ومعلومات المُوقِّع، والسمات الموقَّعة، ومُلخَّص الرسالة، وربط الشهادة، واستخدام المفتاح، والتوقيع، ووقت الإنتاج — وتُختبَر كلّ خطوة بمفردها، بحيث لا تعني عبارة “تَحقَّق الطابع الزمني” إلا أنّ كلّ خطوة قد تَحقَّقت. ويُميَّز فشل الإلغاء اللين (مُستجيب يتعذّر الوصول إليه)، في الشيفرة وفي الاختبارات، عن حالة “مُلغاة” القطعية. ولا يُدمَج الاثنان أبدًا في الإجابة ذاتها.

  1. Integrity Recompute the byte-range digest and compare it to the value the signature covers.
  2. Authenticity Verify the cryptographic signature against the certificate’s public key, over the signed attributes — not the raw content.
  3. Certificate path Build and validate the chain to a trust anchor you chose; every link’s signature, validity, and constraints must hold.
  4. Time Confirm the certificate was valid at the relevant instant, and that the instant is trusted time, not the signer’s clock.
  5. Revocation Confirm the certificate was not revoked at that time, using obtainable or embedded OCSP/CRL evidence.
الأسئلة المستقلة الخمسة التي يُجيب عنها التحقق الصحيح من توقيع PDF، بالترتيب. كلٌّ منها منفصل: اجتياز أحدها لا يقول شيئًا عن البقية، وتجاوُز أيٍّ منها يجعل النتيجة الإجمالية غير مكتملة.

Evidence: Test-backed السلوك مُرتكِز على الاختبارات، و تلك الاختبارات تُنفِّذ ما تتطلّبه المعايير.

السلامة هي Spec: ISO 32000-2, §12.8.1 : يُعاد حساب المُلخَّص فوق نطاق البايتات ويُقارَن بالقيمة المُخزَّنة، وأيّ اختلاف يعني أنّ التوقيع غير صالح. وتغطّي الأصالة فوق السمات الموقَّعة اختبار تكامل يُوقِّع مجموعة سمات موقَّعة حقيقية ويتحقّق منها بالمفتاح العام المطابق عبر عدّة متجهات زمنية. أمّا سؤال مسار الشهادة فهو Spec: RFC 5280, §6.1 : المسارات الصالحة تبدأ من مرتكز ثقة، و Spec: RFC 5280, §6.2 ينصّ على أنّ تلك الخوارزمية تُعرِّف الشروط الدنيا لصلاحية المسار — وأنّ مُتحقِّق المسار في اختبار وحدة يؤكّد أنّ توقيعًا تعرّض للعبث يُنتِج valid = false مع سبب صريح، ولا يقبله بصمت أبدًا.

ترتيب الإلغاء محكوم بـ Spec: RFC 6960, §3.2 : قبل أن يقبل العميل استجابة إلغاء موقَّعة على أنّها صالحة، يجب (SHALL) أن يتأكّد من أنّ توقيع الاستجابة نفسها صالح وأنّ المُوقِّع مُخوَّل حاليًا — و Spec: RFC 6960, §4.2.2.2 يُعرِّف ذلك التخويل بأنّه تفويض id-kp-OCSPSigning صادر مباشرةً عن جهة CA المعنية. لذلك فإنّ إجابة الإلغاء التي لم يجرِ التحقق منها مقابل مُوقِّع مُخوَّل وقابل للتحقق هي إجابة بلا معنى. فحص ربط الشهادة محكوم بـ Spec: RFC 5035, §5.4.2 : إن لم تتطابق تجزئة الشهادة في سمة signing-certificate-v2 الموقَّعة مع الشهادة المُستخدَمة للتحقق من التوقيع، وجب اعتبار التوقيع غير صالح. هذا يَسُدّ ثغرة الاستبدال، حيث يتحقّق التوقيع مقابل شهادة يختارها المهاجم. ويُتحقَّق من رمز الطابع الزمني نفسه على نمط Spec: RFC 5652 ككائن CMS، خطوة بخطوة، وتُختبَر كلّ خطوة بمفردها.

الجزء المُفيد ليس استدعاء ⁨API.⁩ بل الأسئلة التي يجب أن تكون قادرًا على الإجابة عنها قبل أن تتصرّف بناءً على نتيجة. عامِل هذا بوصفه قائمة التحقق التي ستُحاسَب عليها في المراجعة.

<?php
declare(strict_types=1);
// A correct validation produces a structured outcome, not one boolean.
// Before you trust a signature, you must be able to answer ALL of these:
//
// integrity : Does the byte-range digest still match? (tamper check)
// authenticity: Does the signature verify over the SIGNED ATTRIBUTES,
// not just the content?
// path : Does the certificate chain to a trust anchor YOU chose,
// with every link valid at the relevant time?
// time : Is the relevant time TRUSTED (a timestamp), or merely the
// signer's self-asserted clock?
// revocation : Was the certificate not revoked at that time, by evidence
// you obtained or that the document embedded?
//
// "valid: true" without an answer to every line above is an incomplete
// result. A path-validation outcome carries a `valid` flag AND a structured
// `reasons` list precisely so a failure says WHY — never a bare false.

إن كان جواب أيّ سطر هو “لا أعرف”، فالحالة الصادقة ليست “صالح.” بل “لم تُحدَّد بعد” — ومعاملة الاثنتين على أنّهما الشيء نفسه هي الخطأ الذي وُجِدت هذه الصفحة لمنعه.

الفخّ هو مساواة “صالح تشفيريًا” بـ”جدير بالثقة.” فالسلامة والأصالة معًا لا تُثبتان إلا أنّ هذه البايتات وقّعها حامل هذا المفتاح. ولا تقولان شيئًا عمّا إذا كانت شهادة المفتاح موثوقة أو سارية أو غير مُلغاة. قد يكون المستند الموقَّع بشهادة مُولَّدة ذاتيًا “صالحًا تشفيريًا” وعديم القيمة. والفخّ المعاكس هو معاملة فحص إلغاء غير محدَّد (المُستجيب غير متصل) على أنّه نجاح — أو على أنّه فشل. وهو ليس هذا ولا ذاك، بل غير معروف، والمُتحقِّق الصحيح يُبلِّغ عنه على أنّه غير معروف بدلًا من التخمين في أيّ من الاتجاهين. علامة الصحّ الخضراء التي تُخفي أيّ الفحوص الخمسة جرى فعليًا ليست نتيجة تحقق، بل قرار اتّخذه شخص آخر نيابةً عنك.

يُجري ⁨NextPDF⁩ الفحوص البنيوية والتشفيرية ويختبرها. لكنّه لا يختار مرتكزات الثقة الخاصة بك ولا يضمن السياسة المبنية عليها. أيّ الشهادات تثق بها هو قرار نشر لا يستطيع المحرك اتّخاذه. والسلسلة التي تتحقّق صحّتها وصولًا إلى مرتكز ما كان ينبغي أن تثق به تظلّ تحقُّقًا لا يمكنك الاعتماد عليه. لا يمكن فحص أدلّة الإلغاء إلّا إذا كانت قابلة للحصول عليها أو مضمَّنة. المُستجيب غير المتصل يُنتِج حالة “غير محدَّدة”، وتحويل ذلك إلى حكم هو خيار سياسة لا خيار محرك. تصف هذه الصفحة مجموعة الفحوص، لا الكفاية القانونية. وما إذا كان لتوقيع جرى التحقق منه أثر قانوني معيّن يعتمد على الشهادة والمُوقِّع والولاية القضائية والالتزام. أمّا كيف تُبقي الأدلّة المضمَّنة هذه الفحوص قابلة للإجابة عنها بمرور الوقت فيُغطّى في التحقق طويل الأمد؛ وآلية نطاق البايتات وراء فحص السلامة موجودة في كيف تستقرّ التواقيع داخل ملف ⁨PDF⁩.

توافر سطح التحقق حسب المستوى:

Signature validation checks — edition availability
Edition Availability
Core

السلامة والأصالة فوق السمات الموقَّعة، بالإضافة إلى التحقق من مسار الشهادة وفق RFC 5280 §6 مقابل مرتكز ثقة مُقدَّم.

Pro

يُضيف التحقق من رمز الطابع الزمني وفق RFC 3161 — أي سؤال الوقت الموثوق، مُفكَّكًا إلى خطوات تُفحَص بصورة مستقلة.

Enterprise

يُضيف تقييم الإلغاء (⁨OCSP/CRL⁩) والتحقق مقابل المواد طويلة الأمد المضمَّنة، مع تمييز النتائج غير المحدَّدة عن النتائج القطعية.

  • فحص السلامة — إعادة حساب مُلخَّص نطاق البايتات ومقارنته بالقيمة التي يغطّيها التوقيع.
  • فحص الأصالة — التحقق من التوقيع التشفيري مقابل المفتاح العام لشهادة التوقيع، فوق السمات الموقَّعة.
  • السمات الموقَّعة — سمات CMS المُصادَق عليها (content-type، وmessage-digest، وsigning-time، وsigning-certificate-v2) التي يُحسَب التوقيع فوقها فعليًا.
  • التحقق من مسار الشهادة — بناء السلسلة وفحصها من شهادة التوقيع إلى مرتكز ثقة مختار (RFC 5280 §6).
  • مرتكز الثقة — جهة إصدار شهادات قرّرت أن تثق بها؛ جذر المسار المقبول.
  • فحص الإلغاء — تحديد ما إذا كانت الشهادة قد أُلغيت في الوقت المعنيّ، عبر ⁨OCSP⁩ أو قائمة ⁨CRL.⁩
  • غير محدَّد — نتيجة إلغاء ليست “جيدة” ولا “مُلغاة” لأنّ الأدلّة تعذّر الحصول عليها؛ وهي ليست نجاحًا وليست فشلًا.