Timestamp Authority (TSA)
TCPDF-Next Pro включает продакшен-готовый клиент RFC 3161 Timestamp Authority (TsaClient) и хелпер DocumentTimestamp, встраивающий подписи /DocTimeStamp для рабочих процессов PAdES B-LTA.
TsaClient
Базовое использование
use Yeeefang\TcpdfNext\Pro\Tsa\TsaClient;
$tsa = new TsaClient(url: 'https://freetsa.org/tsr');
$token = $tsa->timestamp($pdfHash);С аутентификацией
Некоторые корпоративные TSA-серверы требуют учётные данные:
$tsa = new TsaClient(
url: 'https://tsa.corporate.example/rfc3161',
username: 'api-user',
password: 'api-secret',
);Построение RFC 3161 TimeStampReq
Клиент строит соответствующую стандарту структуру ASN.1 TimeStampReq для каждого запроса:
- MessageImprint -- SHA-256 дайджест данных, на которые ставится метка времени.
- Nonce -- Криптографически случайное 64-битное значение для предотвращения атак повторного воспроизведения.
- CertReq -- Установлено в
true, чтобы TSA включил свой сертификат подписания в ответ.
// The hash must be raw binary (32 bytes for SHA-256)
$hash = hash('sha256', $documentBytes, binary: true);
$token = $tsa->timestamp($hash, algorithm: 'sha256');Проверка Nonce
После получения TimeStampResp клиент автоматически:
- Парсит
TSTInfoиз ответа. - Извлекает nonce из
TSTInfo. - Сравнивает его с nonce, отправленным в запросе.
- Выбрасывает
TsaNonceMismatchExceptionпри несовпадении.
try {
$token = $tsa->timestamp($hash);
} catch (\Yeeefang\TcpdfNext\Pro\Tsa\TsaNonceMismatchException $e) {
// Nonce mismatch -- possible MITM or replay attack
log_security_event($e->getMessage());
}Валидация PKIStatus
Клиент валидирует поле PKIStatus в каждом ответе:
| Код | Значение | Поведение клиента |
|---|---|---|
0 | granted | Токен принят |
1 | grantedWithMods | Токен принят с записью предупреждения |
2 | rejection | Выбрасывается TsaRejectedException |
3 | waiting | Не поддерживается; выбрасывается исключение |
4 | revocationWarning | Токен принят с записью предупреждения |
5 | revocationNotification | Выбрасывается TsaCertRevokedException |
DNS Pinning (защита от SSRF)
Для предотвращения Server-Side Request Forgery вы можете привязать имя хоста TSA к конкретному IP-адресу. Клиент использует CURLOPT_RESOLVE для полного обхода DNS-разрешения:
$tsa = new TsaClient(
url: 'https://tsa.corporate.example/rfc3161',
);
// Pin the hostname to a known IP -- DNS is never queried
$tsa->pinDns('tsa.corporate.example', '203.0.113.42', port: 443);Это критически важно в окружениях, где URL TSA поступает из пользовательского ввода или внешней конфигурации и не должен разрешаться в адреса внутренней сети.
mTLS (Mutual TLS)
Корпоративные TSA-серверы часто требуют аутентификацию клиентским сертификатом. Передайте ваш клиентский сертификат и приватный ключ:
$tsa = new TsaClient(
url: 'https://tsa.bank.example/timestamp',
);
$tsa->clientCertificate(
certPath: '/etc/pki/tsa-client.pem',
keyPath: '/etc/pki/tsa-client.key',
keyPassword: 'client-key-pass',
);Базовый cURL-обработчик настраивается с CURLOPT_SSLCERT, CURLOPT_SSLKEY и CURLOPT_SSLCERTPASSWD.
DocumentTimestamp (B-LTA)
DocumentTimestamp добавляет подпись /DocTimeStamp в PDF, что является финальным шагом в рабочем процессе PAdES B-LTA. Эта метка времени покрывает весь документ, включая все предыдущие подписи и DSS (Document Security Store).
use Yeeefang\TcpdfNext\Pro\Tsa\DocumentTimestamp;
use Yeeefang\TcpdfNext\Pro\Tsa\TsaClient;
$tsa = new TsaClient(url: 'https://freetsa.org/tsr');
$stamper = new DocumentTimestamp(
tsaClient: $tsa,
hashAlgorithm: 'sha256',
);
// Apply the document timestamp (incremental save)
$stamper->apply($document);Краткое описание рабочего процесса B-LTA
1. Sign document (PAdES B-B)
2. Add signature timestamp (PAdES B-T)
3. Embed DSS (OCSP + CRL) (PAdES B-LT)
4. Add /DocTimeStamp (PAdES B-LTA) <-- DocumentTimestampПопулярные TSA-серверы
| Провайдер | URL | Аутентификация | Примечания |
|---|---|---|---|
| FreeTSA | https://freetsa.org/tsr | Нет | Бесплатный; подходит для тестирования |
| Sectigo | https://timestamp.sectigo.com | Нет | Продакшен-готовый; бесплатный тариф |
| DigiCert | https://timestamp.digicert.com | Нет | Широко доверяемый |
| GlobalSign | https://timestamp.globalsign.com/tsa/r6advanced1 | Нет | SHA-256 по умолчанию |
| Пользовательский / Корпоративный | Различается | Basic, mTLS, Bearer | Используйте pinDns() + clientCertificate() |
TIP
Для продакшен-документов PAdES B-LTA используйте TSA-провайдера, корневой сертификат которого включён в Adobe Approved Trust List (AATL). Это гарантирует, что метки времени распознаются Adobe Acrobat без ручной настройки доверия.