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

Enterprise รุ่น

รายการที่เชื่อถือได้ (TSL)

การตรวจสอบลายเซ็นของสหภาพยุโรปเริ่มจากข้อเท็จจริงที่เผยแพร่ไว้ นั่นคือผู้ให้บริการรายใดที่ถือสถานะผ่านการรับรอง ข้อเท็จจริงนี้อยู่ในรายการที่เชื่อถือได้ (TSLs) ซึ่งเป็นเอกสาร XML ที่ลงนามแล้วซึ่งแต่ละรัฐสมาชิกเผยแพร่ จัดทำดัชนีโดยรายการของรายการที่เชื่อถือได้ของสหภาพยุโรป (LOTL) NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer เปลี่ยน URL ของ TSL หรือ XML ดิบให้เป็น TslDocument ที่คุณเชื่อถือได้ โดยจะดึงข้อมูลผ่าน HTTPS ที่มีการป้องกัน ตรวจสอบลายเซ็น XMLDSig กับ anchor ที่คุณปักหมุดไว้ แยกวิเคราะห์ XML ที่เสริมความแข็งแกร่ง และปฏิเสธรายการที่ล้าสมัย การเรียกเพิ่มอีกหนึ่งครั้งคือ TslTrustAnchorProvider::buildBundle() จะแปลงบริการ CA/QC ที่ยังใช้งานอยู่ให้เป็นชุด trust anchor ที่มีเวอร์ชัน ทุกเกตล้มเหลวแบบปิด ทุกการปฏิเสธเป็น exception ที่มีชนิดกำหนดไว้

หน้านี้ครอบคลุมการรับข้อมูลรายการและการสร้าง anchor การตรวจสอบเส้นทางใบรับรองอยู่ใน การตรวจสอบลายเซ็น การจับคู่ระดับการรับประกันของ eIDAS อยู่ใน ระดับการรับประกันของ eIDAS การผูก trust ของคอนเทนเนอร์อยู่ใน การผูก trust ของ ASiC

ความสามารถนี้มาพร้อมกับ NextPDF Enterprise (nextpdf/enterprise) และเปิดใช้งานด้วย envelope ใบอนุญาตระดับ Enterprise การติดตั้งที่ไม่มีสิทธิ์นั้นจะไม่โหลดคลาสของความสามารถนี้ เปรียบเทียบรุ่นและขอรับใบอนุญาต

Terminal window
composer require nextpdf/enterprise

การเปิดใช้งานต้องใช้ envelope ใบอนุญาต Enterprise ของคุณ ดู ติดตั้งและตรวจสอบสิทธิ์ คลาสในหน้านี้อยู่ภายใต้ NextPDF\Enterprise\Security\Tsl ส่วนชนิดของนโยบายเครือข่ายอยู่ภายใต้ NextPDF\Enterprise\Security การดึงแบบออนไลน์ยังต้องการ client ตาม PSR-18 และ factory ตาม PSR-17 ใดก็ได้ (เช่น guzzlehttp/guzzle)

ภายใต้มาตรา 22 ของ eIDAS แต่ละรัฐสมาชิกเผยแพร่รายการที่เชื่อถือได้ของผู้ให้บริการ trust ที่ผ่านการรับรองของตน โดยลงนามหรือประทับตราไว้สำหรับการประมวลผลอัตโนมัติ ETSI TS 119 612 กำหนดรูปแบบ XML รายการจะน่าเชื่อถือเท่าที่การตรวจสอบสามอย่างรับรอง ได้แก่ลายเซ็น โครงสร้าง และความสดใหม่ NextPDF ดำเนินการตามลำดับนั้นในรูปของไปป์ไลน์เดียว:

  1. FetchTslFetcher ดึง XML ผ่าน HTTPS เท่านั้น การป้องกัน SSRF จะตรวจสอบโฮสต์ก่อนการส่งออกใด ๆ การตอบสนองถูกจำกัดขนาด และแคชตาม PSR-16 เปิดใช้การตรวจสอบซ้ำด้วย ETag และการอ่านแบบ air-gapped
  2. VerifyTslSignatureVerifier ตรวจสอบลายเซ็น XMLDSig แบบ enveloped ใบรับรองที่ใช้ลงนามต้องเชื่อมโยงไปยัง trust anchor ที่คุณปักหมุดแบบ out-of-band ไม่มีสิ่งใดภายในเอกสารที่ได้รับความเชื่อถือด้วยตัวเอง
  3. ParseTslXmlParser ดึงข้อมูลของ scheme และบริการ TSP ทุกรายการออกมาเป็น TslDocument ที่เปลี่ยนแปลงไม่ได้ เอกสารที่มี DOCTYPE จะถูกปฏิเสธก่อนที่จะสร้างตาราง entity ใด ๆ
  4. Enforce — ช่วงเวลา NextUpdate ของรายการต้องยังไม่ผ่านไป รายการที่ล้าสมัยจะถูกทิ้ง ไม่ถูกนำไปใช้

TslPolicyEnforcer ประกอบทั้งสี่ขั้นตอนเข้าด้วยกัน TslDocument ที่ได้จากมันได้ผ่านทุกเกตแล้ว จากจุดนั้น TslTrustAnchorProvider::buildBundle() จะกรองบริการที่อยู่ในสถานะ granted และเป็นชนิด CA/QC พร้อมกัน แล้วสร้าง EnterpriseCaTrustAnchorBundle ออกมา ได้แก่ anchor PEM ที่ปักหมุด เวอร์ชัน tsl-<territory>-seq<N> และ digest ความสมบูรณ์แบบ SHA-256 ชุดนั้นคือสิ่งที่การตรวจสอบเส้นทางและการผูก trust ของ ASiC นำไปใช้

กลไกเดียวกันครอบคลุมกระบวนการ LOTL ตรวจสอบ LOTL กับ anchor ที่ปักหมุดด้วยมือ แล้วตรวจสอบ TSL ของแต่ละรัฐสมาชิกกับใบรับรองลงนามที่ LOTL ประกาศไว้สำหรับรัฐนั้น

การตัดสินใจที่สำคัญที่สุดคือโปรไฟล์การตรวจสอบที่ตายตัวและน้อยที่สุด แทนที่จะเป็น XMLDSig ทั่วไป การประมวลผลลายเซ็น XML แบบยืดหยุ่น ทั้งเชนของ transform ตามอำเภอใจ การอ้างอิง ID ที่ผู้โจมตีประกาศได้ และความยืดหยุ่นของอัลกอริทึม คือจุดที่ตัวตรวจสอบล้มเหลวในอดีต ดังนั้นตัวตรวจสอบจึงยอมรับโมเดลการประมวลผลเพียงรูปแบบเดียวเท่านั้น ได้แก่ exclusive C14N การอ้างอิงที่ครอบคลุม root และไปป์ไลน์ transform สองขั้นตอน [enveloped-signature, exclusive-C14N] โดยทุกอย่างที่เหลือถูกปฏิเสธแบบ fail-closed ความเชื่อถือไม่เคยเริ่มต้นจากตัวเอกสารเอง ใบรับรอง KeyInfo เชื่อมโยงไปยัง anchor ที่คุณกำหนดไว้เท่านั้น ความสดใหม่อยู่บน TslDocument เอง ดังนั้นทุกเส้นทางของผู้ใช้จึงบังคับใช้มัน แทนที่จะเป็นตัวประกอบเสริมที่เป็นทางเลือกเพียงตัวเดียว ผลลัพธ์คือ kernel ขนาดเล็กที่ทดสอบได้ กำหนดผลได้แน่นอน และซื่อสัตย์เกี่ยวกับสิ่งที่มันปฏิเสธ

ที่มาเชิงออกแบบ: อธิบายลายเซ็นที่ผ่านการรับรอง

จุดเข้าที่ประสานงานไว้: ดึง ตรวจสอบ แยกวิเคราะห์ และตรวจความสดใหม่ในการเรียกครั้งเดียว

public function __construct(
private readonly TslFetcher $fetcher,
private readonly TslSignatureVerifier $verifier,
private readonly TslXmlParser $parser,
) {}
public function fetchAndVerify(string $url): TslDocument
public function verifyXml(string $xml): TslDocument

โยนหรือล้มเหลวด้วย: TslFetchException และ NextPDF\Enterprise\Security\NetworkPolicyViolation จากขั้นตอนการดึง TslSignatureException จากการตรวจสอบลายเซ็น TslParseException จากการแยกวิเคราะห์ จากค่า NextUpdate ที่ไม่เป็น canonical หรือจากรายการที่ล้าสมัย ทั้งสองเมธอดคืนค่า TslDocument เฉพาะเมื่อทุกเกตผ่านแล้วเท่านั้น เกตความล้าสมัยตรงนี้เปรียบเทียบ NextUpdate กับนาฬิการะบบปัจจุบัน

ตัวดึง HTTP พร้อมแคชแบบใช้ ETag และเกตนโยบายเครือข่าย

public function __construct(
private readonly ClientInterface $httpClient,
private readonly RequestFactoryInterface $requestFactory,
private readonly ?CacheInterface $cache = null,
private readonly int $defaultTtlSeconds = 3600,
private readonly int $maxBytes = 16_777_216,
private readonly NetworkPolicy $networkPolicy = NetworkPolicy::ONLINE,
) {}
public function fetch(string $url): string

โยนหรือล้มเหลวด้วย: TslFetchException เมื่อ URL ไม่ใช่ HTTPS โฮสต์ถูกปฏิเสธ (SSRF) สถานะ HTTP ผิดพลาด การตอบสนองมีขนาดเกิน หรือ body ว่างเปล่า NetworkPolicyViolation เมื่อ NetworkPolicy::STRICT_OFFLINE ทำงานอยู่และไม่มี body ที่แคชไว้ body ที่แคชไว้จะรองรับการตรวจสอบซ้ำแบบ 304 Not Modified และเป็น body เดียวที่ให้บริการภายใต้ STRICT_OFFLINE รายการแคชมีอายุตาม $defaultTtlSeconds

ตัวตรวจสอบ XMLDSig สำหรับรายการที่เชื่อถือได้ที่ลงนามแล้ว

public function __construct(
private readonly array $trustAnchorsPem,
private readonly int $clockTolerance = 0,
)
public function verify(string $xml): string

verify() คืนค่า PEM ของใบรับรองที่ใช้ลงนาม โดยพิสูจน์แล้วว่าเชื่อมโยงไปยังหนึ่งใน $trustAnchorsPem คอนสตรัคเตอร์จะโยน InvalidArgumentException เมื่อรายการ anchor ว่างเปล่า $clockTolerance ขยายหน้าต่างความถูกต้องของใบรับรองแบบสมมาตร หน่วยเป็นวินาที

โปรไฟล์ที่ยอมรับนั้นตายตัว อัลกอริทึมลายเซ็น: allowlist ALLOWED_SIG_ALG (rsa-sha256/384/512, ecdsa-sha256/384/512) Digest: allowlist ALLOWED_DIGEST_ALG (SHA-256, SHA-384, SHA-512) Canonicalization: exclusive C14N 1.0 เท่านั้น SHA-1 และ MD5 ถูกปฏิเสธเป็น unsupported_algorithm

โยนหรือล้มเหลวด้วย: TslSignatureException ซึ่งมี reason ที่เครื่องอ่านได้:

Reason codeความหมาย
missing_signatureเอกสารไม่มีองค์ประกอบ ds:Signature
untrusted_signerใบรับรอง KeyInfo ไม่เชื่อมโยงไปยัง anchor ที่กำหนดไว้
invalid_signatureข้อบกพร่องเชิงโครงสร้าง หรือการตรวจสอบ RSA/ECDSA ล้มเหลว
digest_mismatchdigest ของการอ้างอิงไม่ตรงกับเอกสารที่ผ่าน canonicalize แล้ว
unsupported_algorithmอัลกอริทึมลายเซ็นหรือ digest อยู่นอก allowlist
unsupported_transformไปป์ไลน์ canonicalization หรือ transform อยู่นอกโปรไฟล์ที่ตายตัว
expired_anchorใบรับรองในเชนอยู่นอกหน้าต่างความถูกต้อง หรือความถูกต้องแยกวิเคราะห์ไม่ได้

ตัวแยกวิเคราะห์เชิงโครงสร้างที่ไม่ขึ้นกับลายเซ็น ผู้เรียกต้องตรวจสอบก่อนเชื่อถือผลลัพธ์ของมัน TslPolicyEnforcer บังคับลำดับนั้นให้คุณ

public function parse(string $xml): TslDocument

โยนหรือล้มเหลวด้วย: TslParseException เมื่อ XML ประกาศ DOCTYPE (การเสริมความแข็งแกร่งต่อ XXE และ entity-expansion) แยกวิเคราะห์ไม่ได้ ขาด root TrustServiceStatusList หรือมี TSLSequenceNumber ที่ไม่ถูกต้อง คลาสนี้เปิดเผยค่าคงที่ namespace ได้แก่ NS_TSL, NS_DSIG และ NS_TSL_X

TslDocument เป็น value object ที่เปลี่ยนแปลงไม่ได้: schemeTerritory, schemeOperatorName, tslType, sequenceNumber, issueDateTime, nextUpdate, tspServices และ rawXmlSha256 (แฮชหลักฐานเหนือไบต์ดิบ)

public function isStale(DateTimeImmutable $now): bool
public function assertFresh(DateTimeImmutable $now): void
public function servicesOfType(string $serviceTypeIdentifier): array
public function activeServices(): array

โยนหรือล้มเหลวด้วย: isStale() และ assertFresh() โยน TslParseException เมื่อ nextUpdate ไม่ใช่ dateTime แบบ canonical UTC ที่มี Z หรือ offset ตัวเลขอย่างชัดเจน รายการที่ล้าสมัยทำให้ assertFresh() โยน activeServices() คืนเฉพาะบริการในสถานะ granted เท่านั้น servicesOfType() กรองตาม URI ชนิดบริการของ ETSI

แต่ละรายการ TspService เปิดเผย tspName, serviceName, serviceTypeIdentifier, serviceStatus, statusStartingTime, serviceCertificatePem, qualifiers และ additionalServiceInformation รวมทั้ง:

public function isGranted(): bool
public function isQualifiedCa(): bool

ค่าคงที่ที่มีประโยชน์: TspService::STATUS_GRANTED, TspService::STATUS_WITHDRAWN, TspService::TYPE_CA_QC, TspService::TYPE_OCSP_QC, TspService::TYPE_TSA_QTST URI ของ qualifier (เช่น TspServiceQualifier::FOR_ESIG, FOR_ESEAL, QSCD_STATEMENT, NO_QSCD) ปรากฏบน TspServiceQualifier สำหรับชั้นการจับคู่ eIDAS

public function buildBundle(TslDocument $tsl, DateTimeImmutable $now): EnterpriseCaTrustAnchorBundle

โยนหรือล้มเหลวด้วย: TslParseException เมื่อ TSL ล้าสมัยที่ $now เมื่อ nextUpdate ไม่ใช่ค่า canonical UTC หรือเมื่อรายการไม่มีบริการ CA/QC ที่ยังใช้งานอยู่

หมายเหตุ BC — กฎความสดใหม่ของ buildBundle($now) buildBundle() ต้องการช่วงเวลาการตรวจสอบและเรียก TslDocument::assertFresh($now) ก่อนดึง anchor แม้แต่ตัวเดียว เวอร์ชันก่อนหน้าสามารถสร้าง anchor จาก TslDocument ที่ตัวแยกวิเคราะห์สร้างขึ้นได้โดยไม่ต้องตรวจความสดใหม่ ผู้เรียกที่ป้อนรายการแคชไว้หรือเก็บถาวรไว้ตอนนี้ต้องส่งช่วงเวลาที่การตรวจสอบของตนทำงานเข้ามา รายการที่ล้าสมัยที่ช่วงเวลานั้นจะโยนแทนที่จะปลูกฝัง trust anchor อย่างเงียบ ๆ

EnterpriseCaTrustAnchorBundle ที่คืนกลับมาเป็น value object แบบอ่านอย่างเดียว: anchorsPem (anchor PEM), bundleVersion (tsl-<territory>-seq<N>) และ bundleSha256 (digest ความสมบูรณ์เหนือการต่อ PEM ที่ผ่าน canonicalize แล้ว) รับมันจาก buildBundle() อย่าสร้างมันด้วยมือ คอนสตรัคเตอร์จะโยน InvalidArgumentException เมื่อ digest ไม่ตรงกันหรือ PEM ผิดรูปแบบ

public function containsFingerprint(string $anchorDerSha256Hex): bool
public static function computeBundleSha256(array $anchorsPem): string

ตรวจสอบและใช้งานรายการที่เชื่อถือได้ที่มิเรอร์ไว้ในเครื่อง เส้นทางนี้ไม่ต้องพึ่ง HTTP: ตรวจสอบ แยกวิเคราะห์ แล้วเกตความสดใหม่ที่ช่วงเวลาการตรวจสอบของคุณ

tsl-verify-quickstart.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Security\Tsl\TslParseException;
use NextPDF\Enterprise\Security\Tsl\TslSignatureException;
use NextPDF\Enterprise\Security\Tsl\TslSignatureVerifier;
use NextPDF\Enterprise\Security\Tsl\TslXmlParser;
// The list-signing certificate, pinned OUT-OF-BAND. Never take it from the list itself.
$pinnedAnchorPem = (string) file_get_contents(__DIR__ . '/tsl-signer-anchor.pem');
// A trusted-list XML document you mirrored locally.
$tslXml = (string) file_get_contents(__DIR__ . '/member-state-tsl.xml');
try {
// 1. Authenticate: XMLDSig must verify AND the signer must chain to the pinned anchor.
(new TslSignatureVerifier(trustAnchorsPem: [$pinnedAnchorPem]))->verify($tslXml);
// 2. Parse the now-authenticated bytes.
$tsl = (new TslXmlParser())->parse($tslXml);
// 3. Freshness: refuse a list whose NextUpdate has passed.
$tsl->assertFresh(new DateTimeImmutable('now', new DateTimeZone('UTC')));
} catch (TslSignatureException $e) {
fwrite(STDERR, "TSL rejected ({$e->reason}): {$e->getMessage()}" . PHP_EOL);
exit(1);
} catch (TslParseException $e) {
fwrite(STDERR, 'TSL unusable: ' . $e->getMessage() . PHP_EOL);
exit(1);
}
echo "Territory: {$tsl->schemeTerritory}\n";
echo "Sequence: {$tsl->sequenceNumber}\n";
echo 'Active services: ' . count($tsl->activeServices()) . "\n";

ผลลัพธ์ที่คาดหวัง (ค่าจะต่างกันไปตามรายการ):

Territory: DE
Sequence: 127
Active services: 143

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

tsl-anchor-bundle-production.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
use NextPDF\Enterprise\Security\NetworkPolicy;
use NextPDF\Enterprise\Security\NetworkPolicyViolation;
use NextPDF\Enterprise\Security\Tsl\TslFetchException;
use NextPDF\Enterprise\Security\Tsl\TslFetcher;
use NextPDF\Enterprise\Security\Tsl\TslParseException;
use NextPDF\Enterprise\Security\Tsl\TslPolicyEnforcer;
use NextPDF\Enterprise\Security\Tsl\TslSignatureException;
use NextPDF\Enterprise\Security\Tsl\TslSignatureVerifier;
use NextPDF\Enterprise\Security\Tsl\TslTrustAnchorProvider;
use NextPDF\Enterprise\Security\Tsl\TslXmlParser;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;
// Any PSR-18 client, PSR-17 factory, and PSR-16 cache work; these are examples.
$enforcer = new TslPolicyEnforcer(
fetcher: new TslFetcher(
httpClient: new Client(),
requestFactory: new HttpFactory(),
cache: new Psr16Cache(new FilesystemAdapter('tsl')),
defaultTtlSeconds: 3600,
maxBytes: 16_777_216,
networkPolicy: NetworkPolicy::ONLINE,
),
verifier: new TslSignatureVerifier(
trustAnchorsPem: [(string) file_get_contents(__DIR__ . '/tsl-signer-anchor.pem')],
clockTolerance: 300,
),
parser: new TslXmlParser(),
);
// Use the official publication URL for your scheme territory (HTTPS required).
$tslUrl = 'https://trusted-lists.example.eu/member-state-tsl.xml';
$now = new DateTimeImmutable('now', new DateTimeZone('UTC'));
try {
$tsl = $enforcer->fetchAndVerify($tslUrl);
$bundle = (new TslTrustAnchorProvider())->buildBundle($tsl, $now);
} catch (NetworkPolicyViolation $e) {
// Air-gapped posture: egress forbidden and no cached body available.
fwrite(STDERR, 'Network policy: ' . $e->getMessage() . PHP_EOL);
exit(75);
} catch (TslFetchException $e) {
// Transport layer: SSRF-rejected URL, HTTP error, oversized or empty body.
fwrite(STDERR, 'Fetch failed: ' . $e->getMessage() . PHP_EOL);
exit(1);
} catch (TslSignatureException $e) {
// Authentication layer: treat as a potential attack, not a retry case.
fwrite(STDERR, "Signature rejected ({$e->reason}): {$e->getMessage()}" . PHP_EOL);
exit(1);
} catch (TslParseException $e) {
// Structure or freshness: stale list, malformed NextUpdate, no active CA/QC services.
fwrite(STDERR, 'List unusable: ' . $e->getMessage() . PHP_EOL);
exit(1);
}
printf(
"Anchor bundle %s: %d anchors (sha256 %s...)\n",
$bundle->bundleVersion,
count($bundle->anchorsPem),
substr($bundle->bundleSha256, 0, 12),
);

ผลลัพธ์ที่คาดหวัง (ค่าจะต่างกันไปตามรายการ):

Anchor bundle tsl-de-seq127: 96 anchors (sha256 4b0e2a9f31c8...)

บันทึก bundleVersion และ bundleSha256 ไว้กับทุกการตรวจสอบที่คุณดำเนินการกับชุดนั้น ทั้งสองระบุชุด anchor ที่แน่นอนซึ่งอยู่เบื้องหลังผลแต่ละครั้ง

  • เกตความสดใหม่ของ enforcer ใช้นาฬิกาปัจจุบัน fetchAndVerify() และ verifyXml() ปฏิเสธรายการที่ NextUpdate ผ่านไปแล้ว สำหรับการตรวจสอบย้อนหลังกับรายการที่เก็บถาวรไว้ ให้ขับ TslSignatureVerifier และ TslXmlParser โดยตรง แล้วเรียก assertFresh() ด้วยช่วงเวลาในอดีตที่หลักฐานของคุณรองรับ
  • buildBundle() ยืนยันความสดใหม่ซ้ำที่ $now ของคุณ รายการที่ผ่าน enforcer ยังอาจถูกปฏิเสธที่นี่ได้หากช่วงเวลาการตรวจสอบของคุณอยู่หลังกว่านั้น ดูหมายเหตุ BC ด้านบน
  • อย่าปลูก trustAnchorsPem จากรายการที่คุณกำลังตรวจสอบ anchor ต้องมาจากแหล่งที่ปักหมุดแบบ out-of-band (สำหรับ LOTL) หรือจากรายการแม่ที่ตรวจสอบแล้ว (สำหรับ TSL ของรัฐสมาชิก) อย่างอื่นทำให้การตรวจสอบเป็นวงกลม
  • DOCTYPE ที่ใดก็ตามเป็นข้อผิดพลาดร้ายแรง TSL ที่สอดคล้องตามข้อกำหนดไม่เคยมี DTD ดังนั้นตัวแยกวิเคราะห์จึงปฏิเสธ DOCTYPE ใด ๆ ก่อนที่ libxml จะสร้างตาราง entity นี่เป็นการเสริมความแข็งแกร่งโดยเจตนา ไม่ใช่ข้อจำกัดของตัวแยกวิเคราะห์
  • ฟิลด์เชิงโครงสร้างที่ขาดหายไปจะลดระดับอย่างปลอดภัย บริการที่ไม่มีสถานะที่อ่านได้จะถูกถือว่าถูกถอน จึงไม่มีทางกลายเป็น anchor ได้ scheme territory ที่ขาดหายไปจะถูกแยกวิเคราะห์เป็น unknown ค่าเริ่มต้นแบบ fail-closed กันรายการที่ผิดรูปแบบออกจากวัสดุ trust
  • Intermediate ต้องเป็น CA จริง ระหว่างการสร้างเชน ผู้ออกที่เป็นตัวเลือกซึ่งไม่มี basicConstraints cA=TRUE (หรือยืนยัน keyUsage โดยไม่มี keyCertSign) จะถูกข้าม ใบรับรอง end-entity ที่ลักลอบใส่เข้ามาใน KeyInfo ไม่สามารถทำหน้าที่เป็น intermediate ในเส้นทางได้ เชนถูกจำกัดที่ความลึก 8
  • NextUpdate ต้องเป็น canonical UTC ค่าที่ไม่มี Z หรือ offset ตัวเลขอย่างชัดเจนจะโยน TslParseException ค่านั้นไม่เคยถูกตีความใหม่ในเขตเวลาท้องถิ่นของเซิร์ฟเวอร์
  • รายการขนาดใหญ่และเพดานไบต์ การตอบสนองถูกอ่านได้ถึง $maxBytes (ค่าเริ่มต้น 16 MiB) เพิ่มเพดานในคอนสตรัคเตอร์หากรายการของ scheme ของคุณใหญ่กว่านั้น การถูกตัดจะปรากฏเป็นความล้มเหลวของลายเซ็น ไม่เคยเป็นการยอมรับอย่างเงียบ ๆ
  • clockTolerance ขยายเท่านั้น มันเพิ่มความหย่อนแบบสมมาตรให้การตรวจความถูกต้องของใบรับรอง แต่ไม่ได้ผ่อนคลายเกตความสดใหม่ระดับรายการ
  • ตรวจสอบก่อนแยกวิเคราะห์เสมอ TslXmlParser ไม่ขึ้นกับลายเซ็นโดยการออกแบบ TslPolicyEnforcer จัดลำดับให้ตรวจสอบก่อน หากคุณประกอบชิ้นส่วนด้วยตัวเอง ให้รักษาลำดับนั้นไว้
  • การป้องกัน SSRF แบบเป็นชั้น fetch() ต้องการ https:// และตรวจสอบโฮสต์กับช่วง private, loopback, link-local, CGN และ cloud-metadata พร้อมการแปลง DNS แบบ A และ AAAA เพื่อลดความเสี่ยงจาก rebinding URL ที่ถูกปฏิเสธจะโยนก่อนการส่งออกใด ๆ
  • การเสริมความแข็งแกร่งต่อ XXE และ entity-expansion เอกสารที่มี DOCTYPE จะถูกปฏิเสธก่อนที่ตาราง entity จะมีอยู่และอีกครั้งหลังโหลด การโหลด entity ผ่านเครือข่ายถูกปิดใช้งาน entity ภายนอกไม่เคยถูกแทนที่
  • โปรไฟล์ XMLDSig ที่เข้มงวด exclusive C14N เท่านั้น คู่ transform [enveloped-signature, exclusive-C14N] อย่างแม่นยำ การอ้างอิงที่ตรวจสอบต้องครอบคลุม root ของเอกสาร transform แบบ enveloped จะลบเฉพาะลายเซ็นที่ตรวจสอบแล้ว โดยรักษาลายเซ็นข้างเคียงไว้ อัลกอริทึมที่เลิกใช้แล้ว (SHA-1, MD5) ถูกปฏิเสธ
  • วินัยของเชน ทุกข้อต่อของเชน ทั้งผู้ลงนาม intermediate และกรณี direct-anchor ถูกตรวจความถูกต้องเชิงเวลา โดย fail-closed เมื่อขอบเขตความถูกต้องแยกวิเคราะห์ไม่ได้ ลูปถูกตรวจจับ ความลึกถูกจำกัด
  • ท่าที air-gap ภายใต้ NetworkPolicy::STRICT_OFFLINE เส้นทางการดึงจะไม่ส่งออกภายนอกเลย มีเพียง body ที่แคชไว้ก่อนหน้าที่อาจให้บริการได้ และอย่างอื่นจะโยน NetworkPolicyViolation แบบ fail-fast
  • digest ของชุดตรวจจับการเสียหาย ไม่ใช่การแก้ไขโดยเจตนา bundleSha256 ถูกตรวจสอบตอนสร้างและตรวจจับการคลาดเคลื่อนจากการคัดลอก เมื่อ digest ได้มาจาก anchor ชุดเดียวกับที่มันปกป้อง มันจึงไม่ใช่หลักฐานการถูกแก้ไขที่เป็นอิสระ ปักหมุด digest แบบ out-of-band เมื่อขนย้ายชุดระหว่างระบบ

ไปป์ไลน์นี้รับข้อมูลรายการที่เชื่อถือได้ตามที่ ETSI TS 119 612 กำหนด: มันตรวจสอบลายเซ็นของ scheme operator (§5.7) แยกวิเคราะห์ข้อมูล scheme และโครงสร้างรายการผู้ให้บริการ (§5.3, §5.4, §5.5) บังคับใช้กฎ UTC dateTime (§5.1.3) และทิ้งรายการที่ NextUpdate ผ่านไปแล้ว (§5.3.15) สิ่งนี้รองรับโมเดลรายการที่เชื่อถือได้แบบลงนามและประมวลผลด้วยเครื่องได้ตามมาตรา 22 ของ eIDAS การสร้างเชนใช้เกต basic-constraints และ key-usage ตาม RFC 5280 กับผู้ออกที่เป็นตัวเลือก

การรองรับไม่ใช่ความสอดคล้อง และความสอดคล้องไม่ใช่การรับรอง NextPDF ทำการตรวจสอบตามที่หน้านี้อธิบายไว้ มันยังไม่ได้รับการรับรองเทียบกับ ETSI TS 119 612, eIDAS หรือมาตรฐานอื่นใดโดยหน่วยงานใด และ NextPDF ไม่ถือการรับรองใด ๆ และไม่ให้การรับรองใด ๆ การใช้รายการที่เชื่อถือได้ผ่าน API นี้ไม่ได้ทำให้ลายเซ็น “ผ่านการรับรอง” หรือมีผลทางกฎหมายด้วยตัวมันเอง ว่ากระบวนการตรวจสอบทั้งหมดของคุณจะเป็นไปตามข้อกำหนดทางกฎหมายหรือการจัดซื้อหรือไม่ เป็นการวินิจฉัยของผู้ประเมินของคุณ

การตรวจสอบลายเซ็น TSL รัน RSA และ ECDSA แบบ in-process ผ่านไลบรารีการเข้ารหัสที่มาพร้อมกัน มันไม่ได้ถูกส่งผ่านตัวป้องกันรันไทม์โหมด FIPS ของ Enterprise และการเปิดใช้โหมด FIPS ไม่ได้เปลี่ยนพฤติกรรมของมัน มันไม่ใช่บริการเข้ารหัสที่ผ่านการตรวจสอบ FIPS และไม่มีการอ้างการรับรอง FIPS 140 ใด ๆ การติดตั้งที่มีข้อผูกพัน FIPS ควรกำหนดขอบเขต API นี้ให้เหมาะสมและดู นโยบายการเข้ารหัส FIPS 140-2/3

  • fetch() ส่งออกเฉพาะสำหรับ URL แบบ HTTPS ที่ผ่านการตรวจสอบ SSRF อ่านได้มากที่สุด $maxBytes และปฏิบัติตาม NetworkPolicy ที่กำหนดไว้ ภายใต้ STRICT_OFFLINE จะคืนเฉพาะ body ที่แคชไว้เท่านั้น
  • ไม่มีผลลัพธ์ของตัวแยกวิเคราะห์ใดกลายเป็นวัสดุ trust ก่อนที่ verify() จะสำเร็จ TslPolicyEnforcer รับประกันลำดับนั้น
  • verify() คืนค่า PEM ของผู้ลงนามเฉพาะเมื่อการตรวจ digest และลายเซ็นผ่านภายใต้โปรไฟล์ที่ตายตัว และผู้ลงนามเชื่อมโยงภายในความลึก 8 โดยทุกข้อต่อมีความถูกต้องเชิงเวลาไปยัง anchor ที่กำหนดไว้
  • enforcer ปฏิเสธรายการใดก็ตามที่ NextUpdate ผ่านไปแล้วที่นาฬิกาปัจจุบัน buildBundle() ยืนยันความสดใหม่ซ้ำที่ช่วงเวลาที่ผู้เรียกจัดหาให้ก่อนสร้าง anchor
  • anchor ได้มาจากบริการในสถานะ granted ที่มีชนิดบริการ CA/QC เท่านั้น ชุดที่ใช้งานอยู่ว่างเปล่าจะโยนแทนที่จะให้ชุดว่างเปล่า
  • ทุกความล้มเหลวเป็น exception ที่มีชนิดกำหนดไว้ (TslFetchException, NetworkPolicyViolation, TslSignatureException พร้อม reason code, TslParseException) ไม่มีเมธอดใดคืนเอกสารที่บางส่วนหรือยังไม่ผ่านการตรวจสอบ

NextPDF Core ตรวจสอบลายเซ็น PDF กับ trust anchor ที่คุณปักหมุดอย่างชัดเจนผ่านสัญญา CaTrustAnchorBundle ของมัน ดู Core security Core ไม่มีความสามารถรายการที่เชื่อถือได้: ไม่มีการดึง TSL ไม่มีการตรวจสอบรายการ XMLDSig ไม่มีการแยกวิเคราะห์ ETSI TS 119 612 และไม่มีการสร้าง anchor จากรายการบริการที่ผ่านการรับรอง ด้วย Core เพียงอย่างเดียว คุณต้องดูแลชุด anchor ของคุณด้วยมือ การสร้างมันจากรายการที่เชื่อถือได้ของสหภาพยุโรปที่ผ่านการตรวจสอบต้องใช้ NextPDF Enterprise

หน้านี้บันทึกเฉพาะพฤติกรรมที่สังเกตได้จากภายนอกและพื้นผิว API สาธารณะที่รองรับเท่านั้น เส้นทาง namespace ภายใน คลาสตัวช่วย ตารางกลไก ชื่อไฟล์ runbook และคำนำหน้า ticket อยู่นอกขอบเขต