Timestamp Authority (TSA)
O TCPDF-Next Pro inclui um cliente Timestamp Authority RFC 3161 pronto para produção (TsaClient) e um helper DocumentTimestamp que incorpora assinaturas /DocTimeStamp para workflows PAdES B-LTA.
TsaClient
Uso Básico
use Yeeefang\TcpdfNext\Pro\Tsa\TsaClient;
$tsa = new TsaClient(url: 'https://freetsa.org/tsr');
$token = $tsa->timestamp($pdfHash);Com Autenticação
Alguns servidores TSA corporativos requerem credenciais:
$tsa = new TsaClient(
url: 'https://tsa.corporate.example/rfc3161',
username: 'api-user',
password: 'api-secret',
);Construção do TimeStampReq RFC 3161
O cliente constrói uma estrutura ASN.1 TimeStampReq compatível com o padrão para cada requisição:
- MessageImprint -- Digest SHA-256 dos dados a serem timestampados.
- Nonce -- Valor aleatório criptográfico de 64 bits para prevenir ataques de replay.
- CertReq -- Definido como
truepara que o TSA inclua seu certificado de assinatura na resposta.
// The hash must be raw binary (32 bytes for SHA-256)
$hash = hash('sha256', $documentBytes, binary: true);
$token = $tsa->timestamp($hash, algorithm: 'sha256');Verificação de Nonce
Após receber o TimeStampResp, o cliente automaticamente:
- Analisa o
TSTInfoda resposta. - Extrai o nonce do
TSTInfo. - Compara-o com o nonce enviado na requisição.
- Lança
TsaNonceMismatchExceptionse forem diferentes.
try {
$token = $tsa->timestamp($hash);
} catch (\Yeeefang\TcpdfNext\Pro\Tsa\TsaNonceMismatchException $e) {
// Nonce mismatch -- possible MITM or replay attack
log_security_event($e->getMessage());
}Validação de PKIStatus
O cliente valida o campo PKIStatus em cada resposta:
| Código | Significado | Comportamento do Cliente |
|---|---|---|
0 | granted | Token aceito |
1 | grantedWithMods | Token aceito com aviso registrado |
2 | rejection | TsaRejectedException lançada |
3 | waiting | Não suportado; exceção lançada |
4 | revocationWarning | Token aceito com aviso registrado |
5 | revocationNotification | TsaCertRevokedException lançada |
DNS Pinning (Proteção SSRF)
Para prevenir Server-Side Request Forgery, você pode fixar o hostname do TSA a um endereço IP específico. O cliente usa CURLOPT_RESOLVE para ignorar a resolução DNS completamente:
$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);Isso é crítico em ambientes onde a URL do TSA origina de input do usuário ou configuração externa e não deve resolver para endereços de rede interna.
mTLS (Mutual TLS)
Servidores TSA corporativos frequentemente requerem autenticação por certificado de cliente. Passe seu certificado de cliente e chave privada:
$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',
);O handle cURL subjacente é configurado com CURLOPT_SSLCERT, CURLOPT_SSLKEY e CURLOPT_SSLCERTPASSWD.
DocumentTimestamp (B-LTA)
O DocumentTimestamp adiciona uma assinatura /DocTimeStamp ao PDF, que é o passo final em um workflow PAdES B-LTA. Este timestamp cobre o documento inteiro incluindo todas as assinaturas anteriores e o 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);Resumo do Workflow 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) <-- DocumentTimestampServidores TSA Populares
| Provedor | URL | Autenticação | Notas |
|---|---|---|---|
| FreeTSA | https://freetsa.org/tsr | Nenhuma | Gratuito; adequado para testes |
| Sectigo | https://timestamp.sectigo.com | Nenhuma | Nível de produção; tier gratuito |
| DigiCert | https://timestamp.digicert.com | Nenhuma | Amplamente confiável |
| GlobalSign | https://timestamp.globalsign.com/tsa/r6advanced1 | Nenhuma | SHA-256 padrão |
| Personalizado / Empresarial | Varia | Basic, mTLS, Bearer | Use pinDns() + clientCertificate() |
TIP
Para documentos PAdES B-LTA de produção, use um provedor TSA cujo certificado raiz esteja na Adobe Approved Trust List (AATL). Isso garante que os timestamps sejam reconhecidos pelo Adobe Acrobat sem configuração manual de confiança.