ข้ามไปยังเนื้อหา

ตรวจหาลายเซ็นที่มีอยู่และทำความเข้าใจขอบเขตความเชื่อถือ

ใช้ตัวตรวจสอบของ Core เพื่อตรวจหาว่า PDF มีลายเซ็นหรือไม่ และทำให้ขอบเขตความเชื่อถือชัดเจน การตรวจหาการมีอยู่ไม่ใช่การตรวจสอบความถูกต้อง รุ่น Premium หรือตัวตรวจสอบภายนอกเป็นส่วนที่จัดการการตรวจสอบทางการเข้ารหัสลับ การตรวจสอบเส้นทางความเชื่อถือ และการตรวจสอบการเพิกถอน

  • ติดตั้ง Core แล้ว: composer require nextpdf/core:^3
  • ไฟล์ PDF ที่จะตรวจสอบ
  1. อ่านข้อมูลไบต์ของ PDF
  2. สร้าง Inspector แล้วเรียก inspect()
  3. อ่านค่า InspectResult::$hasSigned โดย true หมายความว่าไฟล์มีพจนานุกรมลายเซ็น
  4. อ่านค่า InspectResult::$isEncrypted และแฟล็กความเสี่ยงเพื่อดูบริบทแวดล้อม
  5. ส่งต่อไฟล์ไปยังตัวตรวจสอบเพื่อให้ได้คำตัดสินทางการเข้ารหัสลับ ตัวตรวจสอบของ Core รายงานเฉพาะการมีอยู่ ไม่ใช่ความถูกต้องสมบูรณ์

แผนภาพด้านล่างแสดงขอบเขตนี้: การมีอยู่ไม่ใช่ความถูกต้องสมบูรณ์ รวมถึงขั้นตอนที่ตัวตรวจสอบซึ่งใช้ตัดสินจริงยังต้องดำเนินการ

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 รายงานว่าไฟล์มีพจนานุกรมลายเซ็น การมีอยู่นี้ไม่ได้ตรวจสอบโครงสร้าง Cryptographic Message Syntax (CMS) ไดเจสต์ของ byte-range ใบรับรองที่ใช้ลงลายเซ็น ห่วงโซ่ใบรับรอง หรือสถานะการเพิกถอน ไฟล์ที่ถูกดัดแปลงก็ยังสามารถรายงานว่า hasSigned = true ได้ อย่าถือว่าการมีอยู่เป็นหลักฐานยืนยันความสมบูรณ์หรือความเป็นเจ้าของโดยเด็ดขาด
  • สิ่งที่การตรวจสอบแบบสมบูรณ์ต้องใช้ คำตัดสินที่ครบถ้วนต้องคำนวณไดเจสต์ของ byte-range ใหม่และเปรียบเทียบ (ISO 32000-2 §12.8.1) ตรวจสอบ CMS SignedData สร้างและตรวจสอบเส้นทาง X.509 ไปยังจุดยึดความเชื่อถือที่เลือกไว้ และตรวจสอบการเพิกถอนผ่าน Online Certificate Status Protocol (OCSP) หรือรายการเพิกถอนใบรับรอง (CRL) สำหรับอินพุตระยะยาว ข้อมูลการตรวจสอบจะอยู่ใน Document Security Store (DSS) (ETSI EN 319 142-2 §6.3.1) การดำเนินการเหล่านี้อยู่ภายใต้สัญญา SignerInterface และ LtvManagerInterface โดยมีการนำไปใช้งานจริงมาให้ในรุ่น Pro และ Enterprise ตัวตรวจสอบภายนอกก็เป็นอีกแนวทางหนึ่งที่รองรับ
  • ระดับความลึกของการตรวจสอบและ sidecar (SIDECAR-001) ค่าเริ่มต้นของ new Inspector() ไม่ได้กำหนดค่า Spectrum sidecar ไว้ หากไม่มี sidecar จะมีเพียง InspectDepth::Quick เท่านั้นที่คืนค่าผลลัพธ์ InspectDepth::Quick ใช้ทางเลือกสำรอง PHP แบบ in-process ส่วน InspectDepth::Standard และ InspectDepth::Full ทั้งคู่ต้องใช้ sidecar เมื่อไม่มี sidecar ให้ใช้งาน ทั้งคู่จะโยน 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
ข้อมูลการตรวจสอบระยะยาวจะอยู่ใน DSSETSI EN 319 142-2§6.3.1

สูตรนี้ตรวจหาว่ามีลายเซ็นหรือไม่เท่านั้น ไม่ได้ยืนยันว่าลายเซ็นใดถูกต้องสมบูรณ์ เชื่อถือได้ หรือยังไม่ถูกเพิกถอน การตัดสินนั้นเป็นหน้าที่ของตัวตรวจสอบทางการเข้ารหัสลับ