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

Contracts / การลงนาม

โดเมนการลงนามประกอบด้วยสัญญาหกรายการ สัญญาเหล่านี้กำหนดวิธีสร้างลายเซ็นแบบ Cryptographic Message Syntax (CMS) การประทับเวลาแบบ Request for Comments (RFC) 3161 การลงนามด้วยคีย์ในโมดูลความปลอดภัยฮาร์ดแวร์ (HSM) และการเปิดใช้การตรวจสอบความถูกต้องระยะยาว (LTV) Core เป็นผู้เผยแพร่สัญญา ส่วนรุ่น Pro และ Enterprise มาพร้อมการนำไปใช้งานจริง

Terminal window
composer require nextpdf/core:^3

ลายเซ็นดิจิทัลของ Portable Document Format (PDF) คือโครงสร้าง CMS SignedData ที่จัดเก็บอยู่ในพจนานุกรมลายเซ็น รายการ Contents เก็บโครงสร้างที่เข้ารหัสแบบ Distinguished Encoding Rules (DER) รายการ ByteRange ระบุช่วงไบต์ที่ไดเจสต์ครอบคลุม ไดเจสต์ครอบคลุมทั้งไฟล์และไม่รวมค่าลายเซ็นเอง ดู International Organization for Standardization (ISO) 32000-2 §12.8.1 โครงสร้าง CMS เป็นไปตาม RFC 5652 §5.1 ซึ่งประกอบด้วยเวอร์ชัน อัลกอริทึมไดเจสต์ เนื้อหาที่ห่อหุ้ม และข้อมูลผู้ลงนาม

SignerInterface คือสัญญาหลัก สัญญานี้สร้าง CMS SignedData สำหรับช่วงไบต์ ใช้การประทับเวลากับค่าลายเซ็น และรายงานว่ารองรับ LTV หรือไม่ สัญญานี้รองรับ PDF Advanced Electronic Signatures (PAdES) ตั้งแต่ระดับพื้นฐาน B-B จนถึง B-LTA ตามที่กำหนดโดย European Telecommunications Standards Institute (ETSI) EN 319 142 ระดับที่สูงขึ้นแต่ละระดับจะเพิ่มข้อมูลการตรวจสอบความถูกต้อง B-B มีลายเซ็นพื้นฐาน B-T เพิ่มการประทับเวลาลายเซ็น B-LT เพิ่มข้อมูลการเพิกถอน B-LTA เพิ่มการประทับเวลาเพื่อการเก็บถาวร

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

TimestampProviderInterface ร้องขอโทเค็นการประทับเวลาแบบ RFC 3161 โปรโตคอลเป็นการแลกเปลี่ยนแบบคำขอ-การตอบกลับกับ Time-Stamping Authority (TSA) ดู RFC 3161 §2.4 ค่า messageImprint ในโทเค็นคือแฮชของค่าลายเซ็น ดู RFC 3161 §2.4.2 LtvManagerInterface เปิดใช้ LTV สัญญานี้รวบรวมสายโซ่ใบรับรอง ดึงการตอบกลับแบบ Online Certificate Status Protocol (OCSP) และ certificate revocation list (CRL) สร้าง Document Security Store (DSS) และเพิ่มการประทับเวลาเอกสารสำหรับ B-LTA CryptoPolicyInterface ควบคุมอัลกอริทึมแฮช ลายเซ็น และการเข้ารหัสลับที่อนุญาต รวมถึงความแข็งแรงของคีย์ ก่อนให้การดำเนินการเชิงรหัสลับใดเริ่มทำงาน

ชนิดประเภทสมาชิกสำคัญความเสถียรตั้งแต่
SignerInterfaceinterfacesign(string): SignatureResult, timestamp(string): string, supportsLtv(): boolstable1.0.0
HsmSignerInterfaceinterfacesign(string, string): string, getCertificateDer(), getCertificateChainDer(), getPublicKeyAlgorithm()stable1.0.0
DeferredSignerInterfaceinterfacesubmitForSigning(string): string, retrieveSignature(string), isComplete(string) (ขยาย SignerInterface)experimental3.0.0
TimestampProviderInterfaceinterfacegetTimestamp(string): stringexperimental3.0.0
LtvManagerInterfaceinterfaceenableLtv(...), addDocumentTimestamp(...)stable1.10.0
CryptoPolicyInterfaceinterfaceisHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName()stable1.9.0

SignerInterface::sign() คืนค่า NextPDF\Security\Signature\SignatureResult คุณสมบัติสาธารณะ $cmsSignedData มี CMS ที่เข้ารหัสแบบ DER คุณสมบัติสาธารณะ $digestHex มีไดเจสต์ SHA-256 คุณสมบัติสาธารณะ $timestampToken มีโทเค็น TSA ที่เป็นทางเลือก ตัวเข้าถึงได้แก่ toHex() / toHexPadded(int) / getSize() / hasTimestamp() HsmSignerInterface::sign() คืนค่าไบต์ที่เข้ารหัสแบบ DER สำหรับ Rivest-Shamir-Adleman (RSA) และไบต์ r‖s แบบดิบสำหรับ Elliptic Curve Digital Signature Algorithm (ECDSA) อาร์กิวเมนต์อัลกอริทึมใช้ตัวระบุของ OpenSSL

examples/contracts/signing-quickstart.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\SignerInterface;
/**
* Sign a byte range with any SignerInterface implementation.
*
* @param SignerInterface $signer A core or Premium signer.
* @param string $byteRange The PDF byte range to sign.
*
* @return string Hex-encoded CMS SignedData for the PDF /Contents field.
*/
function signByteRange(SignerInterface $signer, string $byteRange): string
{
$result = $signer->sign($byteRange);
return $result->toHex();
}

SignerInterface::sign() คืนค่า SignatureResult toHex() ให้สตริงฐานสิบหกที่ตัวเขียนนำไปวางในฟิลด์ /Contents ส่วนไบต์ DER แบบดิบอยู่ในคุณสมบัติสาธารณะ $cmsSignedData ฟังก์ชันนี้ขึ้นอยู่กับสัญญา ไม่ใช่คลาสรูปธรรม ทั้งผู้ลงนามทดสอบของ Core และผู้ลงนาม HSM ของ Premium ต่างก็เป็นไปตามสัญญานี้

examples/contracts/signing-production.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\CryptoPolicyInterface;
use NextPDF\Contracts\SignerInterface;
use NextPDF\Contracts\TimestampProviderInterface;
use NextPDF\Exception\NextPdfException;
use Psr\Log\LoggerInterface;
final readonly class TimestampedSigningService
{
public function __construct(
private SignerInterface $signer,
private TimestampProviderInterface $timestamps,
private CryptoPolicyInterface $policy,
private LoggerInterface $logger,
) {}
/**
* Sign a byte range, then timestamp the CMS structure.
*
* @param string $byteRange The PDF byte range to sign.
*
* @return array{cms: string, digest: string, tst: string}
*/
public function sign(string $byteRange): array
{
if (!$this->policy->isHashAlgorithmAllowed($this->policy->getPreferredHashAlgorithm())) {
throw new \LogicException('Preferred hash rejected by crypto policy.');
}
try {
$signature = $this->signer->sign($byteRange);
$token = $this->timestamps->getTimestamp($signature->cmsSignedData);
return [
'cms' => $signature->toHex(),
'digest' => $signature->digestHex,
'tst' => $token,
];
} catch (NextPdfException $e) {
$this->logger->error('Signing failed', [
'policy' => $this->policy->getName(),
'error' => $e->getMessage(),
]);
throw $e;
}
}
}

บริการนี้แทรกสัญญาสามรายการ และตรวจสอบนโยบายการเข้ารหัสลับก่อนลงนาม SignatureResult เปิดเผยไบต์ CMS ผ่านคุณสมบัติสาธารณะ $cmsSignedData ไดเจสต์ SHA-256 ผ่าน $digestHex และสตริงฐานสิบหก /Contents ผ่าน toHex() ผู้ให้บริการประทับเวลารับไบต์ CMS และคืนค่าโทเค็นที่เข้ารหัสแบบ DER บล็อก catch บันทึกชื่อนโยบายและส่งข้อยกเว้นต่อ โดยไม่กลืนความล้มเหลว

  • ไดเจสต์ของช่วงไบต์ต้องไม่รวมค่าลายเซ็น ไดเจสต์ที่ครอบคลุมรายการ Contents จะสร้างลายเซ็นที่ไม่มีทางตรวจสอบได้ ดู ISO 32000-2 §12.8.1
  • SignerInterface::supportsLtv() รายงานความสามารถ ไม่ใช่สถานะ ผู้ลงนามสามารถรองรับ LTV และยังคงสร้างลายเซ็น B-B ได้เมื่อไม่ได้กำหนดค่าบริการประทับเวลา
  • DeferredSignerInterface::retrieveSignature() คืนค่า null จนกว่างานจะเสร็จสิ้น ควรตรวจสอบ isComplete() ก่อน เพื่อไม่ให้ถ่ายโอนเพย์โหลดในการตรวจสอบทุกครั้ง การดึงข้อมูลเป็นแบบ idempotent เมื่อมีผลลัพธ์อยู่แล้ว
  • LtvManagerInterface::addDocumentTimestamp() ต้องทำงานหลังจากเขียน Document Security Store แล้ว การเรียกใช้ก่อนจะสร้างโครงสร้าง B-LTA ที่ไม่ถูกต้อง
  • CryptoPolicyInterface คืนค่า true สำหรับทุกอัลกอริทึมเมื่อไม่ได้ตั้งค่านโยบาย ในสภาพแวดล้อมที่มีการกำกับดูแล ให้ตั้งค่านโยบายอย่างชัดเจน อย่าพึ่งพาค่าเริ่มต้นที่เปิดกว้าง
  • HsmSignerInterface::getCertificateChainDer() ไม่รวมใบรับรองผู้ลงนาม ใช้ getCertificateDer() สำหรับใบรับรองปลายทางของผู้ลงนาม และใช้เมธอดสายโซ่สำหรับใบรับรองตัวกลาง

ต้นทุนการลงนามส่วนใหญ่มาจากการดำเนินการเชิงรหัสลับและการรับส่งข้อมูลผ่านเครือข่าย ไม่ใช่จากสัญญา ลายเซ็นซอฟต์แวร์ในเครื่องโดยทั่วไปใช้เวลาระดับมิลลิวินาทีหลักเดียว ลายเซ็น HSM เพิ่มการรับส่งข้อมูลกับอุปกรณ์ การประทับเวลาเพิ่มการรับส่งข้อมูลผ่านเครือข่ายไปยัง Time-Stamping Authority การตรวจสอบความถูกต้องระยะยาวเพิ่มการดึง OCSP หรือ CRL หนึ่งครั้งต่อใบรับรองหนึ่งใบในสายโซ่ ค่า performance_budget ที่ 1500 ms wall ครอบคลุมลายเซ็นเดียวที่ประทับเวลากับ TSA ระยะไกลบนการเชื่อมต่อที่อุ่นแล้ว การตรวจสอบความถูกต้องระยะยาวกับปลายทางการเพิกถอนที่ช้าจะเกินค่านี้ และควรทำงานนอกเส้นทางคำขอ โปรไฟล์การทำซ้ำได้คือ structural ไม่ใช่ bitwise การประทับเวลาฝังเวลาที่ลงนาม ดังนั้นการทำงานสองครั้งจึงต่างกันที่ไบต์ของการประทับเวลา ขณะที่โครงสร้างเอกสารยังคงเหมือนกัน

สัญญาการลงนามเป็นขอบเขตเชิงรหัสลับหลักของเอนจิน ดังนั้นแบบจำลองภัยคุกคามจึงต้องชัดเจน ความปลอดภัยในการเก็บรักษาคีย์เป็นข้อกังวลแรก HsmSignerInterface เก็บคีย์ส่วนตัวไว้ภายในขอบเขตของฮาร์ดแวร์ และสัญญาไม่เปิดเผยข้อมูลคีย์ การลดระดับอัลกอริทึมเป็นข้อกังวลที่สอง CryptoPolicyInterface บล็อกแฮชที่อ่อนแอและคีย์ที่สั้นก่อนดำเนินการ ทำให้การปรับใช้สามารถบังคับใช้โปรไฟล์ Federal Information Processing Standards (FIPS) 140-3 หรือ electronic identification, authentication, and trust services (eIDAS) ได้โดยไม่ต้องแยกเอนจิน ความไว้วางใจในการประทับเวลาเป็นข้อกังวลที่สาม โทเค็น RFC 3161 น่าเชื่อถือได้เท่ากับ Time-Stamping Authority ที่ออกโทเค็นเท่านั้น ดังนั้นสัญญาผู้ให้บริการจึงสามารถแทรกได้ และการปรับใช้กำหนดผู้มีอำนาจของตนเอง การตรวจสอบความถูกต้องระยะยาวเป็นข้อกังวลที่สี่ ข้อมูลการเพิกถอนถูกดึงในเวลาที่ลงนามและจัดเก็บใน Document Security Store เพื่อให้การตรวจสอบความถูกต้องคงอยู่ได้แม้ใบรับรองหมดอายุ จงถือว่าอินพุตของผู้ลงนามทุกตัวไม่น่าเชื่อถือ เอนจินเป็นผู้คำนวณช่วงไบต์ และไม่รับค่านี้จากผู้เรียก หน้านี้ถูกทำเครื่องหมายว่า export_control_class: legal-review-required เนื่องจากสัญญาควบคุมการลงนามเชิงรหัสลับ เนื้อหาถอดความแหล่งข้อมูลเชิงบรรทัดฐานทั้งหมดและไม่ได้อ้างอิงข้อความใดโดยตรง ตามหลักสุขอนามัยการอ้างอิง

ข้อกล่าวอ้างมาตรฐานข้อกำหนดหลักฐาน
รายการ Contents ในพจนานุกรมลายเซ็นจัดเก็บค่าลายเซ็นเป็น CMS SignedData ที่เข้ารหัสแบบ DER หรือเป็น TimeStampTokenISO 32000-2§12.8.1
ไดเจสต์ถูกคำนวณเหนือช่วงไบต์ที่กำหนดโดยอาร์เรย์ ByteRange และไม่รวมค่าลายเซ็นISO 32000-2§12.8.1,
Document Security Store เก็บข้อมูลการตรวจสอบความถูกต้องระยะยาว พร้อมด้วย validation-related information (VRI) OCSP CRL และรายการใบรับรองISO 32000-2§12.8.4.3,
PAdES การตรวจสอบความถูกต้องระยะยาววางข้อมูลการตรวจสอบไว้ในพจนานุกรม DSS และ VRIETSI EN 319 142-2§6.3,
โทเค็นการประทับเวลาแบบ RFC 3161 ผูกแฮชของค่าลายเซ็นผ่าน messageImprint ในการแลกเปลี่ยนแบบคำขอ-การตอบกลับของ TSARFC 3161§2.4.2, §2.4,
ลำดับ CMS SignedData มีเวอร์ชัน อัลกอริทึมไดเจสต์ เนื้อหาที่ห่อหุ้ม และข้อมูลผู้ลงนามRFC 5652§5.1

ข้อกำหนดทุกข้อเป็นการถอดความ NextPDF ไม่ได้ทำซ้ำข้อความเชิงบรรทัดฐาน โปรดศึกษามาตรฐานที่เผยแพร่เพื่อดูถ้อยคำที่เป็นทางการ

Core เป็นผู้เผยแพร่และตรึงสัญญาการลงนาม รุ่น Pro และ Enterprise มาพร้อมการนำไปใช้งานจริงที่อยู่เบื้องหลัง HsmSignerInterface LtvManagerInterface และผู้ลงนามแบบเลื่อนเวลา รวมถึงการผสานฮาร์ดแวร์ Public-Key Cryptography Standards #11 (PKCS#11) และ PAdES B-LT และ B-LTA Core ค้นหาและผูกการนำไปใช้งานเหล่านี้ในขณะรันไทม์ด้วย class_exists() แล้วแปลงเป็นสัญญา ดังนั้นเอนจินโอเพนซอร์สจึงไม่มีการพึ่งพาเชิงพาณิชย์ และ API ไม่เปลี่ยนแปลงเมื่ออัปเกรด

  • Contracts: 41 อินเทอร์เฟซสาธารณะ (SPI) ภาพรวมและระดับความเสถียรของ service provider interface
  • Contracts / Security Policy CryptoPolicyInterface การควบคุมอัลกอริทึมและคีย์
  • Contracts / Extraction การบังคับใช้ PDF/A ที่จับคู่กับการเก็บถาวรแบบมีลายเซ็น
  • Security ขอบเขตการนำการเข้ารหัสลับและลายเซ็นไปใช้งาน
  • Audit การบันทึกการตรวจสอบชื่อนโยบายและเหตุการณ์การลงนาม
  • Exception ลำดับชั้น NextPdfException ที่ถูกโยนโดยผู้ลงนาม