Skip to content

Timestamp Authority (TSA)

Pro — Commercial License Required
La integración TSA RFC 3161 requiere el paquete Pro.

TCPDF-Next Pro incluye un cliente de Time Stamp Authority RFC 3161 de grado producción (TsaClient) y un helper DocumentTimestamp que incrusta firmas /DocTimeStamp para flujos de trabajo PAdES B-LTA.

TsaClient

Uso básico

php
use Yeeefang\TcpdfNext\Pro\Tsa\TsaClient;

$tsa = new TsaClient(url: 'https://freetsa.org/tsr');

$token = $tsa->timestamp($pdfHash);

Con autenticación

Algunos servidores TSA corporativos requieren credenciales:

php
$tsa = new TsaClient(
    url:      'https://tsa.corporate.example/rfc3161',
    username: 'api-user',
    password: 'api-secret',
);

Construcción de TimeStampReq RFC 3161

El cliente construye una estructura ASN.1 TimeStampReq conforme al estándar para cada solicitud:

  1. MessageImprint -- Digest SHA-256 de los datos a firmar con timestamp.
  2. Nonce -- Valor aleatorio criptográfico de 64 bits para prevenir ataques de repetición.
  3. CertReq -- Establecido en true para que la TSA incluya su certificado de firma en la respuesta.
php
// The hash must be raw binary (32 bytes for SHA-256)
$hash = hash('sha256', $documentBytes, binary: true);

$token = $tsa->timestamp($hash, algorithm: 'sha256');

Verificación de nonce

Después de recibir el TimeStampResp, el cliente automáticamente:

  1. Analiza el TSTInfo de la respuesta.
  2. Extrae el nonce del TSTInfo.
  3. Lo compara con el nonce enviado en la solicitud.
  4. Lanza TsaNonceMismatchException si difieren.
php
try {
    $token = $tsa->timestamp($hash);
} catch (\Yeeefang\TcpdfNext\Pro\Tsa\TsaNonceMismatchException $e) {
    // Nonce mismatch -- possible MITM or replay attack
    log_security_event($e->getMessage());
}

Validación de PKIStatus

El cliente valida el campo PKIStatus en cada respuesta:

CódigoSignificadoComportamiento del cliente
0grantedToken aceptado
1grantedWithModsToken aceptado con advertencia registrada
2rejectionSe lanza TsaRejectedException
3waitingNo soportado; se lanza excepción
4revocationWarningToken aceptado con advertencia registrada
5revocationNotificationSe lanza TsaCertRevokedException

DNS Pinning (protección SSRF)

Para prevenir Server-Side Request Forgery, puedes anclar el hostname de la TSA a una dirección IP específica. El cliente usa CURLOPT_RESOLVE para eludir la resolución DNS por completo:

php
$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);

Esto es crítico en entornos donde la URL de la TSA proviene de entrada del usuario o configuración externa y no debe resolver a direcciones de red internas.

mTLS (Mutual TLS)

Los servidores TSA corporativos frecuentemente requieren autenticación con certificado de cliente. Pasa tu certificado de cliente y clave privada:

php
$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',
);

El handle cURL subyacente se configura con CURLOPT_SSLCERT, CURLOPT_SSLKEY y CURLOPT_SSLCERTPASSWD.

DocumentTimestamp (B-LTA)

DocumentTimestamp agrega una firma /DocTimeStamp al PDF, que es el paso final en un flujo de trabajo PAdES B-LTA. Este timestamp cubre todo el documento incluyendo todas las firmas previas y el DSS (Document Security Store).

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

Resumen del flujo de trabajo 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

Servidores TSA populares

ProveedorURLAuthNotas
FreeTSAhttps://freetsa.org/tsrNingunaGratuito; adecuado para testing
Sectigohttps://timestamp.sectigo.comNingunaGrado producción; tier gratuito
DigiCerthttps://timestamp.digicert.comNingunaAmpliamente confiable
GlobalSignhttps://timestamp.globalsign.com/tsa/r6advanced1NingunaSHA-256 por defecto
Personalizado / EmpresarialVaríaBasic, mTLS, BearerUsa pinDns() + clientCertificate()

TIP

Para documentos PAdES B-LTA en producción, usa un proveedor TSA cuyo certificado raíz esté en la Adobe Approved Trust List (AATL). Esto asegura que los timestamps sean reconocidos por Adobe Acrobat sin configuración manual de confianza.

Distribuido bajo la licencia LGPL-3.0-or-later.