Bỏ qua để đến nội dung

Kiểm tra chữ ký hiện có và nắm rõ ranh giới tin cậy

Dùng trình kiểm tra Core để phát hiện liệu một PDF có chữ ký hay không, đồng thời giữ rõ ranh giới tin cậy. Phát hiện không đồng nghĩa với xác minh. Các phiên bản Premium hoặc một trình xác minh bên ngoài sẽ đảm nhận việc xác minh mật mã, kiểm tra đường dẫn tin cậy và kiểm tra thu hồi.

  • Đã cài đặt Core: composer require nextpdf/core:^3.
  • Một tệp PDF cần kiểm tra.
  1. Đọc các byte của PDF.
  2. Tạo một Inspector và gọi inspect().
  3. Đọc InspectResult::$hasSigned. true nghĩa là tệp chứa một từ điển chữ ký.
  4. Đọc InspectResult::$isEncrypted và các cờ rủi ro để có thêm ngữ cảnh liên quan.
  5. Chuyển tệp đến một trình xác minh để nhận quyết định về mặt mật mã. Trình kiểm tra chỉ cho biết sự hiện diện, không cho biết tính hợp lệ.

Sơ đồ dưới đây thể hiện ranh giới: sự hiện diện không phải là tính hợp lệ. Sơ đồ cũng nêu những bước kiểm tra mà một trình xác minh thực thụ vẫn phải thực hiện.

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";
}

Đối với đầu vào đã ký:

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

Đối với đầu vào chưa ký:

No signature found in incoming.pdf
  • Sự hiện diện không phải là tính hợp lệ — ranh giới. InspectResult::$hasSigned cho biết có một từ điển chữ ký tồn tại trong tệp. Nó không kiểm tra cấu trúc Cryptographic Message Syntax (CMS), giá trị băm của byte range, chứng chỉ ký, chuỗi chứng chỉ hay trạng thái thu hồi. Một tệp đã bị giả mạo vẫn có thể báo cáo hasSigned = true. Đừng bao giờ coi sự hiện diện là bằng chứng về tính toàn vẹn hay quyền tác giả.
  • Những gì cần cho xác minh đầy đủ. Một quyết định hoàn chỉnh sẽ tính lại giá trị băm của byte range và so sánh nó (ISO 32000-2 §12.8.1), xác thực CMS SignedData, xây dựng và kiểm tra đường dẫn X.509 tới một trust anchor tin cậy, đồng thời kiểm tra thu hồi qua Online Certificate Status Protocol (OCSP) hoặc danh sách thu hồi chứng chỉ (CRL). Đối với các đầu vào dài hạn, dữ liệu xác thực nằm trong Document Security Store (DSS) (ETSI EN 319 142-2 §6.3.1). Các thao tác này chạy phía sau các hợp đồng SignerInterfaceLtvManagerInterface; các bản triển khai dùng cho sản xuất đi kèm trong các phiên bản Pro và Enterprise. Một trình xác minh bên ngoài là phương án được hỗ trợ còn lại.
  • Độ sâu kiểm tra và sidecar (SIDECAR-001). Một new Inspector() mặc định không có sidecar Spectrum nào được cấu hình. Khi không có sidecar, chỉ InspectDepth::Quick trả về kết quả. InspectDepth::Quick dùng cơ chế dự phòng PHP chạy trong tiến trình. InspectDepth::StandardInspectDepth::Full đều cần sidecar. Nếu không có sidecar nào khả dụng, chúng sẽ ném InspectException với mã INSPECT-SIDECAR-001 (“Spectrum sidecar is required for Standard/Full depth inspection”, retryable = true). Hàm khởi tạo của InspectConfigđộ sâu mặc định là Standard. Do đó, một new InspectConfig() trống (hoặc new InspectConfig(depth: InspectDepth::Standard)) không dùng được ở chế độ ngoại tuyến. Nó ném SIDECAR-001 trước cả khi hasSigned được đọc. Dùng InspectConfig::quick() để phát hiện sự hiện diện ở chế độ ngoại tuyến, như trong công thức này. Không có độ sâu nào thực hiện xác minh chữ ký mật mã trong Core.
  • Đầu vào rỗng. Một chuỗi rỗng sẽ ném InspectException với mã INSPECT-INPUT-001. Hãy bảo vệ bước đọc tệp.
  • Nhiều chữ ký. Cờ hiện diện không đếm số chữ ký và cũng không phân biệt một chữ ký phê duyệt với một dấu thời gian tài liệu. Hãy dùng một trình xác minh chuyên dụng khi số lượng hoặc kết luận riêng cho từng chữ ký là quan trọng.
Phát biểuTiêu chuẩnĐiều khoảnreference_id
Giá trị chữ ký được lưu trong mục Contents của từ điển chữ ký.ISO 32000-2§12.8.1
Việc xác minh tính lại giá trị băm trên ByteRange, loại trừ giá trị chữ ký.ISO 32000-2§12.8.1
Dữ liệu xác thực dài hạn nằm trong DSS.ETSI EN 319 142-2§6.3.1

Công thức này phát hiện liệu có chữ ký hiện diện hay không. Nó không khẳng định rằng bất kỳ chữ ký nào là hợp lệ, được tin cậy hay chưa bị thu hồi. Quyết định đó thuộc về một trình xác minh mật mã.