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

افحص توقيعًا موجودًا وافهم حدود الثقة

استخدم فاحص ⁨Core⁩ لاكتشاف ما إذا كان مستند ⁨PDF⁩ يحتوي على توقيع، واجعل حدود الثقة واضحة. الاكتشاف لا يعني التحقق. تتولى الإصدارات المدفوعة أو أداة تحقق خارجية التحقق التشفيري، والتحقق من مسار الثقة، وفحص الإبطال.

  • تثبيت ⁨Core⁩‏: composer require nextpdf/core:^3.
  • ملف ⁨PDF⁩ لفحصه.
  1. اقرأ بايتات مستند ⁨PDF⁩.
  2. أنشئ كائن Inspector واستدعِ inspect().
  3. اقرأ InspectResult::$hasSigned. القيمة true تعني أن الملف يحتوي على قاموس توقيع.
  4. اقرأ InspectResult::$isEncrypted وأعلام الخطر للسياق المحيط.
  5. وجّه الملف إلى أداة تحقق لاتخاذ القرار التشفيري. يبلّغ الفاحص عن الوجود، لا عن الصلاحية.

يوضّح المخطط أدناه هذا الحد: الوجود ليس صلاحية. كما يبيّن الفحوص التي يجب أن تجريها أداة التحقق الفعلية.

false

true

Yes

No

Yes

No / unknown

Incoming PDF

Inspector.inspect — Quick

hasSigned?

No signature present

Signature dictionary PRESENT

NOT yet validity

Recompute byte-range digest

ISO 32000-2 §12.8.1

Validate CMS SignedData

Build & check X.509 path

to a chosen trust anchor

Check revocation OCSP / CRL

Long-term input?

Read DSS validation material

All checks evaluated

Every check passed?

Trustworthy

Not trusted — do not act

Diagram
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Inspect\Inspector;
use NextPDF\Inspect\InspectConfig;
$pdfData = file_get_contents(__DIR__ . '/incoming.pdf');
if ($pdfData === false || $pdfData === '') {
fwrite(STDERR, "Cannot read incoming.pdf\n");
exit(1);
}
$inspector = new Inspector();
// InspectConfig::quick() selects InspectDepth::Quick. This is the only
// depth that runs offline: a default Inspector has no Spectrum sidecar,
// and without a sidecar Quick is the sole path that returns a result.
// Standard and Full require the sidecar (see the SIDECAR-001 edge case).
$result = $inspector->inspect(
$pdfData,
InspectConfig::quick(),
);
// hasSigned reports the PRESENCE of a signature dictionary.
// It does NOT mean the signature verifies.
if ($result->hasSigned) {
echo "A signature is present in incoming.pdf\n";
echo "Encrypted: " . ($result->isEncrypted ? 'yes' : 'no') . "\n";
echo "Next step: run a cryptographic verifier before trusting it.\n";
} else {
echo "No signature found in incoming.pdf\n";
}

لمُدخل موقَّع:

A signature is present in incoming.pdf
Encrypted: no
Next step: run a cryptographic verifier before trusting it.

لمُدخل غير موقَّع:

No signature found in incoming.pdf
  • الوجود ليس صلاحية — الحد الفاصل. يبلّغ InspectResult::$hasSigned بأن قاموس توقيع موجود في الملف. وهو لا يفحص بنية الرسالة التشفيرية ‏(⁨CMS⁩)، ولا ملخص نطاق البايتات، ولا شهادة التوقيع، ولا سلسلة الشهادات، ولا حالة الإبطال. يمكن لملف جرى العبث به أن يبلّغ مع ذلك عن hasSigned = true. لا تعدّ الوجود مطلقًا دليلًا على السلامة أو جهة الإنشاء.
  • ما يحتاجه التحقق الكامل. يعيد القرار الكامل حساب ملخص نطاق البايتات ويقارنه ‏(⁨ISO 32000-2⁩ §12.8.1)، ويتحقق من ⁨CMS SignedData⁩، ويبني مسار ⁨X.509⁩ إلى مرتكز ثقة موثوق ويفحصه، ويفحص الإبطال عبر بروتوكول حالة الشهادة عبر الإنترنت ‏(⁨OCSP⁩) أو قائمة إبطال الشهادات ‏(⁨CRL⁩). في المُدخلات طويلة الأمد، توجد بيانات التحقق في مخزن أمان المستند ‏(⁨DSS⁩) ‏(⁨ETSI EN 319 142-2⁩ §6.3.1). تجري هذه العمليات خلف عقدَي SignerInterface وLtvManagerInterface؛ وتُشحن تطبيقاتها الإنتاجية في إصداري ⁨Pro⁩ و⁨Enterprise⁩. أداة التحقق الخارجية هي المسار الآخر المدعوم.
  • عمق الفحص والمكوّن الجانبي ‏(⁨SIDECAR-001⁩). لا يحتوي new Inspector() الافتراضي على أي مكوّن جانبي ⁨Spectrum⁩ مهيَّأ. من دون مكوّن جانبي، لا يُرجع نتيجة إلا InspectDepth::Quick. يستخدم InspectDepth::Quick البديل الاحتياطي ضمن عملية ⁨PHP⁩. يتطلّب كلٌّ من InspectDepth::Standard وInspectDepth::Full المكوّن الجانبي. إذا لم يتوفّر أي مكوّن جانبي، فإنهما يطرحان InspectException برمز INSPECT-SIDECAR-001 ‏(“⁨Spectrum sidecar is required for Standard/Full depth inspection⁩”، retryable = true). العمق الافتراضي لمُنشئ InspectConfig هو Standard. لذلك فإن new InspectConfig() المجرّد (أو new InspectConfig(depth: InspectDepth::Standard)) غير قابل للاستخدام دون اتصال. فهو يطرح ⁨SIDECAR-001⁩ قبل أن تُقرأ hasSigned أصلًا. استخدم InspectConfig::quick() لاكتشاف الوجود دون اتصال، كما تفعل هذه الوصفة. لا يجري أي عمق تحققًا تشفيريًا من التوقيع في ⁨Core⁩.
  • مُدخل فارغ. تطرح السلسلة الفارغة InspectException برمز INSPECT-INPUT-001. احرس قراءة الملف.
  • توقيعات متعددة. لا يحصي عَلَم الوجود التوقيعات ولا يميّز توقيع الموافقة عن طابع زمني للمستند. استخدم أداة تحقق مخصصة عندما يكون العدد أو الحكم لكل توقيع مهمًا.
العبارةالمواصفةالبند⁨reference_id⁩
تُخزَّن قيمة التوقيع في مدخلة Contents في قاموس التوقيع.⁨ISO 32000-2⁩§12.8.1
يعيد التحقق حساب الملخص على ByteRange، مع استبعاد قيمة التوقيع.⁨ISO 32000-2⁩§12.8.1
توجد بيانات التحقق طويلة الأمد في ⁨DSS.⁩⁨ETSI EN 319 142-2⁩§6.3.1

تكتشف هذه الوصفة ما إذا كان هناك توقيع موجود. وهي لا تؤكّد أن أي توقيع صالح أو موثوق أو غير مُبطَل. ذلك القرار يعود إلى أداة تحقق تشفيرية.