タイムスタンプ局(TSA)
TCPDF-Next Proには、本番グレードのRFC 3161タイムスタンプ局クライアント(TsaClient)と、PAdES B-LTAワークフロー用の/DocTimeStamp署名を埋め込むDocumentTimestampヘルパーが含まれています。
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.enterprise.example/rfc3161',
username: 'api-user',
password: 'api-secret',
);RFC 3161 TimeStampReq の構築
クライアントは、リクエストごとに標準準拠のTimeStampReq ASN.1構造を構築します:
- MessageImprint -- タイムスタンプ対象データのSHA-256ダイジェスト。
- Nonce -- リプレイ攻撃を防ぐための暗号的にランダムな64ビット値。
- CertReq -- TSAがレスポンスに署名証明書を含めるように
trueに設定。
// ハッシュは生のバイナリである必要があります(SHA-256の場合32バイト)
$hash = hash('sha256', $documentBytes, binary: true);
$token = $tsa->timestamp($hash, algorithm: 'sha256');ノンス検証
TimeStampRespを受信後、クライアントは自動的に以下を行います:
- レスポンスから
TSTInfoを解析。 TSTInfoからノンスを抽出。- リクエストで送信したノンスと比較。
- 一致しない場合は
TsaNonceMismatchExceptionをスロー。
try {
$token = $tsa->timestamp($hash);
} catch (\Yeeefang\TcpdfNext\Pro\Tsa\TsaNonceMismatchException $e) {
// ノンス不一致 -- MITM攻撃またはリプレイ攻撃の可能性
log_security_event($e->getMessage());
}PKIStatus の検証
クライアントはすべてのレスポンスのPKIStatusフィールドを検証します:
| コード | 意味 | クライアントの動作 |
|---|---|---|
0 | granted | トークン受理 |
1 | grantedWithMods | 警告ログ付きでトークン受理 |
2 | rejection | TsaRejectedExceptionをスロー |
3 | waiting | サポート対象外、例外をスロー |
4 | revocationWarning | 警告ログ付きでトークン受理 |
5 | revocationNotification | TsaCertRevokedExceptionをスロー |
DNSピニング(SSRF防御)
サーバーサイドリクエストフォージェリを防ぐために、TSAホスト名を特定のIPアドレスにピン留めできます。クライアントはCURLOPT_RESOLVEを使用してDNS解決を完全にバイパスします:
$tsa = new TsaClient(
url: 'https://tsa.enterprise.example/rfc3161',
);
// ホスト名を既知のIPにピン留め -- DNSは問い合わせされません
$tsa->pinDns('tsa.enterprise.example', '203.0.113.42', port: 443);これは、TSA URLがユーザー入力や外部設定から取得され、内部ネットワークアドレスに解決されてはならない環境で重要です。
mTLS(相互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はPDFに/DocTimeStamp署名を追加します。これはPAdES B-LTAワークフローの最終ステップです。このタイムスタンプは、すべての以前の署名とDSS(ドキュメントセキュリティストア)を含むドキュメント全体をカバーします。
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',
);
// ドキュメントタイムスタンプを適用(増分保存)
$stamper->apply($document);B-LTAワークフローの概要
1. ドキュメントに署名 (PAdES B-B)
2. 署名タイムスタンプを追加 (PAdES B-T)
3. DSSを埋め込み (OCSP + CRL) (PAdES B-LT)
4. /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ドキュメントには、ルート証明書がAdobe Approved Trust List(AATL)に含まれるTSAプロバイダを使用してください。これにより、Adobe Acrobatで手動の信頼設定なしにタイムスタンプが認識されます。