Skip to content

Chữ ký số (HasSecurity)

Trait HasSecurity cung cấp setSignature() cho chữ ký số tuân thủ PAdES. TCPDF-Next hỗ trợ bốn cấp chữ ký — từ cơ bản (B-B) đến lưu trữ (B-LTA) — qua PadesOrchestrator, TsaClient và các module LTV. Mọi method chữ ký trả về static để chain.

Tham chiếu nhanh

Class / EnumMục đích
CertificateInfoTải chứng chỉ ký (PEM hoặc PKCS#12)
SignatureLevelEnum: PAdES_B_B, PAdES_B_T, PAdES_B_LT, PAdES_B_LTA
TsaClientClient RFC 3161 timestamp authority
SignatureAppearanceWidget chữ ký hiển thị hoặc ẩn
OcspClientKiểm tra thu hồi trực tuyến RFC 6960
CrlFetcherTải CRL distribution point RFC 5280

Cấp chữ ký

CấpBao gồmHiệu lực
B-B (Basic)Chữ ký + chứng chỉ kýHợp lệ khi chứng chỉ chưa bị thu hồi
B-T (Timestamp)B-B + RFC 3161 timestampChứng minh chữ ký tồn tại trước thời điểm cụ thể
B-LT (Long-Term)B-T + DSS với OCSP/CRL responseXác minh được sau khi chứng chỉ hết hạn
B-LTA (Archival)B-LT + document timestamp + vòng lưu trữXác minh được vô thời hạn

Vòng đời chữ ký PAdES

mermaid
sequenceDiagram
    participant App
    participant Core
    participant TSA as TSA Server
    participant OCSP as OCSP Responder
    App->>Core: sign(certificate, key)
    Core->>Core: PAdES B-B (embedded)
    Core->>TSA: RFC 3161 timestamp
    TSA-->>Core: Timestamp token
    Core->>Core: PAdES B-T
    Core->>OCSP: Certificate check
    OCSP-->>Core: OCSP response
    Core->>Core: PAdES B-LT
    Core->>Core: PAdES B-LTA (archive)

Tải chứng chỉ

Từ file PEM

php
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;

$cert = CertificateInfo::fromFiles(
    certPath: '/path/to/certificate.pem',
    keyPath: '/path/to/private-key.pem',
    password: 'key-password',
    extraCerts: '/path/to/ca-chain.pem',  // chứng chỉ trung gian tùy chọn
);

Từ PKCS#12 (.p12 / .pfx)

php
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;

$cert = CertificateInfo::fromPkcs12(
    p12Path: '/path/to/certificate.p12',
    password: 'pkcs12-password',
);

Ví dụ ký

php
use Yeeefang\TcpdfNext\Core\Document;
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;
use Yeeefang\TcpdfNext\Contracts\SignatureLevel;
use Yeeefang\TcpdfNext\Security\Timestamp\TsaClient;

$cert = CertificateInfo::fromFiles(
    certPath: '/path/to/certificate.pem',
    keyPath: '/path/to/private-key.pem',
    password: 'key-password',
);

// PAdES B-B (Basic) — chỉ chữ ký
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_B)
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->cell(0, 10, 'Signed document (B-B)')
    ->save('signed-bb.pdf');

// PAdES B-T (Timestamp) — chữ ký + timestamp
$tsa = new TsaClient('https://freetsa.org/tsr');
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_T, $tsa)
    ->addPage()
    ->cell(0, 10, 'Signed with timestamp (B-T)')
    ->save('signed-bt.pdf');

// PAdES B-LTA (Archival) — long-term validation đầy đủ
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_LTA, $tsa)
    ->addPage()
    ->cell(0, 10, 'Archival signature (B-LTA)')
    ->save('signed-blta.pdf');

TsaClient hỗ trợ xác thực tùy chọn. Xác minh nonce và DNS pinning được bật mặc định để ngăn chặn tấn công replay và SSRF.

php
$tsa = new TsaClient(
    url: 'https://tsa.example.com/timestamp',
    user: 'tsa-user',
    pass: 'tsa-password',
);

Long-Term Validation (B-LT / B-LTA)

Cho cấp B-LT và B-LTA, dữ liệu thu hồi được tải và nhúng tự động:

  • OcspClient — truy vấn OCSP responder (RFC 6960) từ extension AIA của chứng chỉ
  • CrlFetcher — tải CRL từ distribution point (RFC 5280)
  • DSS — lưu OCSP response và CRL trong Document Security Store
  • VRI — dữ liệu validation theo chữ ký (tùy chọn, theo khuyến nghị ETSI)

B-LTA còn thêm document timestamp, kích hoạt vòng lưu trữ — document có thể được re-timestamp để kéo dài hiệu lực vô thời hạn.

Giao diện chữ ký

Mặc định, chữ ký ẩn. Để tạo widget chữ ký hiển thị:

php
use Yeeefang\TcpdfNext\Security\Signature\SignatureAppearance;

$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_T, $tsa)
    ->setSignatureAppearance(
        SignatureAppearance::visible(x: 20, y: 250, w: 80, h: 30)
    )
    ->addPage()
    ->cell(0, 10, 'Document with visible signature')
    ->save('visible-signature.pdf');

Cho chữ ký ẩn rõ ràng:

php
$pdf->setSignatureAppearance(SignatureAppearance::invisible());

Thuật toán và tham chiếu Method

Thuật toán chữ ký qua phpseclib3: RSA PKCS#1 v1.5 (mặc định, tương thích rộng nhất) và RSASSA-PSS (padding mạnh hơn, khuyên dùng cho triển khai mới).

php
$pdf->setSignature(
    CertificateInfo   $cert,           // Chứng chỉ và private key
    SignatureLevel    $level,           // B-B, B-T, B-LT, hoặc B-LTA
    ?TsaClient        $tsa   = null,   // Bắt buộc cho B-T, B-LT, B-LTA
);

Trả về static để chain. Chữ ký được áp dụng trong save() hoặc output().

Phân phối theo giấy phép LGPL-3.0-or-later.