Skip to content

타임스탬프 기관 (TSA)

Pro — Commercial License Required
RFC 3161 TSA 통합은 Pro 패키지가 필요합니다.

TCPDF-Next Pro는 프로덕션급 RFC 3161 타임스탬프 기관 클라이언트(TsaClient)와 PAdES B-LTA 워크플로를 위한 /DocTimeStamp 서명을 임베딩하는 DocumentTimestamp 헬퍼를 제공합니다.

TsaClient

기본 사용법

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

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

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

인증을 사용한 경우

일부 엔터프라이즈 TSA 서버는 자격 증명이 필요합니다:

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

RFC 3161 TimeStampReq 구성

클라이언트는 모든 요청에 대해 표준을 준수하는 TimeStampReq ASN.1 구조를 빌드합니다:

  1. MessageImprint -- 타임스탬프할 데이터의 SHA-256 다이제스트.
  2. Nonce -- 리플레이 공격을 방지하기 위한 암호학적으로 안전한 64비트 랜덤 값.
  3. CertReq -- TSA가 응답에 서명 인증서를 포함하도록 true로 설정.
php
// 해시는 원시 바이너리여야 합니다 (SHA-256의 경우 32바이트)
$hash = hash('sha256', $documentBytes, binary: true);

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

논스 검증

TimeStampResp를 수신한 후 클라이언트는 자동으로:

  1. 응답에서 TSTInfo를 파싱합니다.
  2. TSTInfo에서 논스를 추출합니다.
  3. 요청에서 보낸 논스와 비교합니다.
  4. 불일치하면 TsaNonceMismatchException을 발생시킵니다.
php
try {
    $token = $tsa->timestamp($hash);
} catch (\Yeeefang\TcpdfNext\Pro\Tsa\TsaNonceMismatchException $e) {
    // 논스 불일치 -- MITM 또는 리플레이 공격 가능성
    log_security_event($e->getMessage());
}

PKIStatus 검증

클라이언트는 모든 응답에서 PKIStatus 필드를 검증합니다:

코드의미클라이언트 동작
0granted토큰 승인
1grantedWithMods경고를 로깅하고 토큰 승인
2rejectionTsaRejectedException 발생
3waiting지원되지 않음; 예외 발생
4revocationWarning경고를 로깅하고 토큰 승인
5revocationNotificationTsaCertRevokedException 발생

DNS 핀닝 (SSRF 보호)

서버 측 요청 위조(SSRF)를 방지하기 위해 TSA 호스트명을 특정 IP 주소에 핀닝할 수 있습니다. 클라이언트는 CURLOPT_RESOLVE를 사용하여 DNS 해석을 완전히 우회합니다:

php
$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 서버는 클라이언트 인증서 인증을 자주 요구합니다. 클라이언트 인증서와 개인 키를 전달하세요:

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

기본 cURL 핸들은 CURLOPT_SSLCERT, CURLOPT_SSLKEY, CURLOPT_SSLCERTPASSWD로 구성됩니다.

DocumentTimestamp (B-LTA)

DocumentTimestamp는 PDF에 /DocTimeStamp 서명을 추가하며, 이는 PAdES B-LTA 워크플로의 마지막 단계입니다. 이 타임스탬프는 이전의 모든 서명과 DSS(문서 보안 저장소)를 포함한 전체 문서를 커버합니다.

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

// 문서 타임스탬프 적용 (증분 저장)
$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인증비고
FreeTSAhttps://freetsa.org/tsr없음무료; 테스트용으로 적합
Sectigohttps://timestamp.sectigo.com없음프로덕션급; 무료 티어
DigiCerthttps://timestamp.digicert.com없음광범위하게 신뢰됨
GlobalSignhttps://timestamp.globalsign.com/tsa/r6advanced1없음SHA-256 기본값
커스텀 / 엔터프라이즈다양Basic, mTLS, BearerpinDns() + clientCertificate() 사용

TIP

프로덕션 PAdES B-LTA 문서의 경우, Adobe 승인 신뢰 목록(AATL)에 루트 인증서가 포함된 TSA 제공업체를 사용하세요. 이렇게 하면 수동 신뢰 구성 없이 Adobe Acrobat에서 타임스탬프가 인식됩니다.

LGPL-3.0-or-later 라이선스로 배포됩니다.