tc-lib-pdf-sign

July 16, 2026 ยท View on GitHub

Digital signature primitives for PDF documents (PKCS#7, CAdES, PAdES).

Latest Stable Version Build Coverage License Downloads

Sponsor on GitHub

๐Ÿ’– Part of the tc-lib-pdf / TCPDF ecosystem (100M+ installs). Sponsor its maintenance โ†’


Overview

tc-lib-pdf-sign provides the cryptographic building blocks and PDF signature objects used by tc-lib-pdf to produce signed PDF documents. The crypto and the PDF object generation live here, while the host library keeps the ByteRange placement, the incremental update writer, and the public facade.

The package assembles CMS/CAdES signatures natively in pure PHP (via a small DER ASN.1 codec), so it can embed the ESS signing-certificate-v2 attribute that openssl_pkcs7_sign() cannot add. This is what lifts a plain PKCS#7 signature to a PAdES baseline signature.

Namespace\Com\Tecnick\Pdf\Sign
AuthorNicola Asuni info@tecnick.com
LicenseGNU LGPL v3 - see LICENSE
API docshttps://tcpdf.org/docs/srcdoc/tc-lib-pdf-sign
Packagisthttps://packagist.org/packages/tecnickcom/tc-lib-pdf-sign

Features

Signature profiles (each level builds on the previous one):

Profile/SubFilterWhat it provides
Legacyadbe.pkcs7.detachedISO 32000-1 detached CMS (now carrying the ESS signing-certificate-v2 attribute).
PAdES B-BETSI.CAdES.detachedCAdES-based CMS with content-type, message-digest, and signing-certificate-v2 signed attributes.
PAdES B-TETSI.CAdES.detachedB-B plus an RFC 3161 signature timestamp embedded as the id-aa-signatureTimeStampToken unsigned attribute.
PAdES B-LTETSI.CAdES.detachedB-T plus a Document Security Store (/DSS, /VRI) with certificate, OCSP, and CRL validation material.
PAdES B-LTAETSI.CAdES.detached + ETSI.RFC3161B-LT plus a /Type /DocTimeStamp archive timestamp for long-term archival.
  • RSA and ECDSA signing keys, with SHA-256, SHA-384, or SHA-512 digests.
  • Both the local (private key) and the external/remote (HSM) signing workflows are supported through the tc-lib-pdf facade, which builds on these primitives.
  • The PAdES baseline output has been validated against the EU DSS reference validator (B-B, B-T, B-LT, B-LTA all report the expected baseline level).

Components

ComponentResponsibility
ConfigImmutable signature configuration (profile, digest algorithm, certification level) with /SubFilter derivation.
SignerOrchestration entry point: builds the detached CAdES CMS and collects the LTV material, tying the pieces below together.
Cms\BuilderNative detached CAdES-BES SignedData builder (signs the DER signed attributes with openssl_sign()).
Cms\Asn1Minimal DER ASN.1 encoder/decoder for CMS, RFC 3161, and OCSP structures.
Timestamp\Client / Timestamp\ConfigRFC 3161 timestamp request/response codec.
Ocsp\ClientRFC 6960 OCSP request builder and response fetcher.
Ltv\ValidationMaterialDSS material collection: certificate dedup, AIA/CRL-DP URL extraction, OCSP/CRL retrieval.
Output\SignatureThe /Sig value dictionary, including the /ByteRange and /Contents placeholders.
Output\WidgetSignature and empty-field widget annotations.
Output\DssDSS/VRI object emitter.
Output\DocTimeStampThe /Type /DocTimeStamp value object (B-LTA).
Output\PdfStringShared PDF string-token encoder.
ExceptionLibrary exception type.

Design

The codecs are pure and perform no file or network access. HTTP transports (TSA, OCSP, CRL) and key loading are injected by the host as callables, so the consuming application owns networking and SSRF protection. This keeps the package deterministic and testable, and lets the host reuse its existing HTTP stack and URL allow-list.


Requirements

  • PHP 8.2 or later
  • Extensions: hash, openssl
  • Composer

Installation

composer require tecnickcom/tc-lib-pdf-sign

This package is normally pulled in transitively by tc-lib-pdf; install it directly only when you need the low-level primitives on their own.


Usage

For signing PDF documents, use the tc-lib-pdf fluent signature() facade, which drives this package end to end:

$pdf->signature()->configure([
    'profile'          => 'pades-b-t',   // legacy | pades-b-b | pades-b-t | pades-b-lt | pades-b-lta
    'digest_algorithm' => 'sha256',      // sha256 | sha384 | sha512
    'signcert'         => 'file:///path/to/cert.pem',
    'privkey'          => 'file:///path/to/key.pem',
    'password'         => '',
]);

See the full guide in tc-lib-pdf/doc/DIGITAL_SIGNATURES.md and the runnable E007/E008/E009/E081 signature examples in tc-lib-pdf.

Low-level: building a detached CMS

Cms\Builder produces a detached CAdES-BES CMS over arbitrary bytes (the host supplies the ByteRange-covered content). It is the core of PAdES B-B:

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Com\Tecnick\Pdf\Sign\Cms\Builder;

$privateKey = openssl_pkey_get_private('file:///path/to/key.pem');
$certDer    = '';   // DER bytes of the signing certificate
$content    = '';   // detached content bytes (the ByteRange-covered document)

$cms = (new Builder())->sign(
    $content,        // detached content bytes (the ByteRange-covered document)
    $certDer,        // DER of the signing certificate
    $privateKey,     // OpenSSLAsymmetricKey (RSA or EC)
    [],              // additional chain certificates (DER), if any
    'sha256',        // digest algorithm
    time(),          // signing time (Unix timestamp)
);

// $cms is a DER-encoded CMS ContentInfo ready for injection into /Contents.

Standards

  • ETSI EN 319 142-1 - PAdES baseline profiles (B-B, B-T, B-LT, B-LTA)
  • ISO 32000-1 / ISO 32000-2 - PDF digital signatures and the Document Security Store
  • RFC 5652 - Cryptographic Message Syntax (CMS)
  • RFC 5035 - ESS signing-certificate-v2 attribute
  • RFC 3161 - Time-Stamp Protocol (TSP)
  • RFC 6960 - Online Certificate Status Protocol (OCSP)
  • RFC 5280 - X.509 certificates and CRLs

Development

make deps
make help
make qa

Packaging

make rpm
make deb

For system packages, bootstrap with:

require_once '/usr/share/php/Com/Tecnick/Pdf/Sign/autoload.php';

Contributing

Contributions are welcome. Please review CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md.