Skip to content

Digital Signatures (HasSecurity)

The HasSecurity trait provides setSignature() for PAdES-compliant digital signatures. TCPDF-Next supports four signature levels — from basic (B-B) to archival (B-LTA) — through the PadesOrchestrator, TsaClient, and LTV modules. All signature methods return static for chaining.

Quick Reference

Class / EnumPurpose
CertificateInfoLoad signing certificates (PEM or PKCS#12)
SignatureLevelEnum: PAdES_B_B, PAdES_B_T, PAdES_B_LT, PAdES_B_LTA
TsaClientRFC 3161 timestamp authority client
SignatureAppearanceVisible or invisible signature widget
OcspClientRFC 6960 online revocation checking
CrlFetcherRFC 5280 CRL distribution point fetching

Signature Levels

LevelWhat It IncludesValidity
B-B (Basic)Signature + signing certificateValid while certificate is not revoked
B-T (Timestamp)B-B + RFC 3161 timestampProves signature existed before a point in time
B-LT (Long-Term)B-T + DSS with OCSP/CRL responsesVerifiable after certificate expires
B-LTA (Archival)B-LT + document timestamp + archival loopVerifiable indefinitely

Loading Certificates

From PEM Files

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',  // optional intermediate certificates
);

From PKCS#12 (.p12 / .pfx)

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

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

Signing Examples

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) — signature only
$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) — signature + 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) — full long-term validation
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_LTA, $tsa)
    ->addPage()
    ->cell(0, 10, 'Archival signature (B-LTA)')
    ->save('signed-blta.pdf');

The TsaClient supports optional authentication. Nonce verification and DNS pinning are enabled by default to prevent replay attacks and SSRF.

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

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

For B-LT and B-LTA levels, revocation data is fetched and embedded automatically:

  • OcspClient — queries OCSP responders (RFC 6960) from the certificate's AIA extension
  • CrlFetcher — downloads CRLs from distribution points (RFC 5280)
  • DSS — stores OCSP responses and CRLs in the Document Security Store
  • VRI — per-signature validation data (optional, per ETSI recommendation)

B-LTA additionally adds a document timestamp, enabling the archival loop — the document can be re-timestamped to extend validity indefinitely.

Signature Appearance

By default, signatures are invisible. To create a visible signature widget:

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');

For an explicitly invisible signature:

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

Algorithms and Method Reference

Signature algorithms via phpseclib3: RSA PKCS#1 v1.5 (default, widest compatibility) and RSASSA-PSS (stronger padding, recommended for new deployments).

php
$pdf->setSignature(
    CertificateInfo   $cert,           // Certificate and private key
    SignatureLevel    $level,           // B-B, B-T, B-LT, or B-LTA
    ?TsaClient        $tsa   = null,   // Required for B-T, B-LT, B-LTA
);

Returns static for chaining. The signature is applied during save() or output().

Released under the LGPL-3.0-or-later License.