Skip to content

Цифровые подписи (HasSecurity)

Trait HasSecurity предоставляет setSignature() для цифровых подписей, соответствующих PAdES. TCPDF-Next поддерживает четыре уровня подписей — от базового (B-B) до архивного (B-LTA) — через PadesOrchestrator, TsaClient и модули LTV. Все методы подписей возвращают static для цепочки вызовов.

Краткий справочник

Класс / EnumНазначение
CertificateInfoЗагрузка сертификатов подписи (PEM или PKCS#12)
SignatureLevelEnum: PAdES_B_B, PAdES_B_T, PAdES_B_LT, PAdES_B_LTA
TsaClientКлиент для сервера временных меток RFC 3161
SignatureAppearanceВидимый или невидимый виджет подписи
OcspClientОнлайн-проверка отзыва RFC 6960
CrlFetcherЗагрузка CRL из точек распространения RFC 5280

Уровни подписей

УровеньЧто включаетСрок действия
B-B (Базовый)Подпись + сертификат подписиДействительна, пока сертификат не отозван
B-T (Временная метка)B-B + временная метка RFC 3161Доказывает существование подписи до определённого момента
B-LT (Долгосрочный)B-T + DSS с ответами OCSP/CRLПроверяема после истечения сертификата
B-LTA (Архивный)B-LT + временная метка документа + архивный циклПроверяема бессрочно

Жизненный цикл подписи 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)

Загрузка сертификатов

Из 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',  // опциональные промежуточные сертификаты
);

Из PKCS#12 (.p12 / .pfx)

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

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

Примеры подписания

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 (Базовый) — только подпись
$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 (Временная метка) — подпись + временная метка
$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 (Архивный) — полная долгосрочная валидация
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_LTA, $tsa)
    ->addPage()
    ->cell(0, 10, 'Archival signature (B-LTA)')
    ->save('signed-blta.pdf');

TsaClient поддерживает опциональную аутентификацию. Проверка nonce и DNS-привязка включены по умолчанию для предотвращения атак повторного воспроизведения и SSRF.

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

Долгосрочная валидация (B-LT / B-LTA)

Для уровней B-LT и B-LTA данные об отзыве загружаются и встраиваются автоматически:

  • OcspClient — запрашивает OCSP-серверы (RFC 6960) из расширения AIA сертификата
  • CrlFetcher — загружает CRL из точек распространения (RFC 5280)
  • DSS — хранит ответы OCSP и CRL в Document Security Store
  • VRI — данные валидации для каждой подписи (опционально, по рекомендации ETSI)

B-LTA дополнительно добавляет временную метку документа, включая архивный цикл — документ может быть повторно подписан для бессрочного продления действительности.

Внешний вид подписи

По умолчанию подписи невидимы. Для создания видимого виджета подписи:

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

Для явно невидимой подписи:

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

Алгоритмы и справочник методов

Алгоритмы подписей через phpseclib3: RSA PKCS#1 v1.5 (по умолчанию, наибольшая совместимость) и RSASSA-PSS (более сильное дополнение, рекомендуется для новых развёртываний).

php
$pdf->setSignature(
    CertificateInfo   $cert,           // Сертификат и закрытый ключ
    SignatureLevel    $level,           // B-B, B-T, B-LT или B-LTA
    ?TsaClient        $tsa   = null,   // Обязателен для B-T, B-LT, B-LTA
);

Возвращает static для цепочки вызовов. Подпись применяется при вызове save() или output().

Распространяется по лицензии LGPL-3.0-or-later.