디지털 서명 (HasSecurity)
HasSecurity 트레이트는 PAdES 준수 디지털 서명을 위한 setSignature()를 제공합니다. TCPDF-Next는 PadesOrchestrator, TsaClient 및 LTV 모듈을 통해 기본(B-B)부터 보관(B-LTA)까지 네 가지 서명 레벨을 지원합니다. 모든 서명 메서드는 체이닝을 위해 static을 반환합니다.
빠른 참조
| 클래스 / 열거형 | 용도 |
|---|---|
CertificateInfo | 서명 인증서 로드 (PEM 또는 PKCS#12) |
SignatureLevel | 열거형: PAdES_B_B, PAdES_B_T, PAdES_B_LT, PAdES_B_LTA |
TsaClient | RFC 3161 타임스탬프 기관 클라이언트 |
SignatureAppearance | 가시적 또는 비가시적 서명 위젯 |
OcspClient | RFC 6960 온라인 폐지 확인 |
CrlFetcher | RFC 5280 CRL 배포 지점 가져오기 |
서명 레벨
| 레벨 | 포함 내용 | 유효성 |
|---|---|---|
| B-B (기본) | 서명 + 서명 인증서 | 인증서가 폐지되지 않은 동안 유효 |
| B-T (타임스탬프) | B-B + RFC 3161 타임스탬프 | 특정 시점 이전에 서명이 존재했음을 증명 |
| B-LT (장기) | B-T + OCSP/CRL 응답이 포함된 DSS | 인증서 만료 후에도 검증 가능 |
| B-LTA (보관) | B-LT + 문서 타임스탬프 + 보관 루프 | 무기한 검증 가능 |
인증서 로드
PEM 파일에서
php
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;
$cert = CertificateInfo::fromFiles(
certPath: '/path/to/certificate.pem',
keyPath: '/path/to/private-key.pem',
password: 'key-password',
extraCerts: '/path/to/ca-chain.pem', // 선택적 중간 인증서
);PKCS#12에서 (.p12 / .pfx)
php
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;
$cert = CertificateInfo::fromPkcs12(
p12Path: '/path/to/certificate.p12',
password: 'pkcs12-password',
);서명 예제
php
use Yeeefang\TcpdfNext\Core\Document;
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;
use Yeeefang\TcpdfNext\Contracts\SignatureLevel;
use Yeeefang\TcpdfNext\Security\Timestamp\TsaClient;
$cert = CertificateInfo::fromFiles(
certPath: '/path/to/certificate.pem',
keyPath: '/path/to/private-key.pem',
password: 'key-password',
);
// PAdES B-B (기본) — 서명만
$pdf = Document::create()
->setSignature($cert, SignatureLevel::PAdES_B_B)
->addPage()
->setFont('Helvetica', '', 12)
->cell(0, 10, 'Signed document (B-B)')
->save('signed-bb.pdf');
// PAdES B-T (타임스탬프) — 서명 + 타임스탬프
$tsa = new TsaClient('https://freetsa.org/tsr');
$pdf = Document::create()
->setSignature($cert, SignatureLevel::PAdES_B_T, $tsa)
->addPage()
->cell(0, 10, 'Signed with timestamp (B-T)')
->save('signed-bt.pdf');
// PAdES B-LTA (보관) — 전체 장기 검증
$pdf = Document::create()
->setSignature($cert, SignatureLevel::PAdES_B_LTA, $tsa)
->addPage()
->cell(0, 10, 'Archival signature (B-LTA)')
->save('signed-blta.pdf');TsaClient는 선택적 인증을 지원합니다. 재생 공격 및 SSRF를 방지하기 위해 Nonce 검증과 DNS 고정이 기본적으로 활성화되어 있습니다.
php
$tsa = new TsaClient(
url: 'https://tsa.example.com/timestamp',
user: 'tsa-user',
pass: 'tsa-password',
);장기 검증 (B-LT / B-LTA)
B-LT 및 B-LTA 레벨의 경우, 폐지 데이터가 자동으로 가져와지고 임베드됩니다:
- OcspClient -- 인증서의 AIA 확장에서 OCSP 응답자를 쿼리 (RFC 6960)
- CrlFetcher -- 배포 지점에서 CRL 다운로드 (RFC 5280)
- DSS -- Document Security Store에 OCSP 응답과 CRL 저장
- VRI -- 서명별 검증 데이터 (ETSI 권장사항에 따른 선택 사항)
B-LTA는 추가로 문서 타임스탬프를 추가하여 보관 루프를 활성화합니다 -- 유효성을 무기한 연장하기 위해 문서에 재타임스탬프를 적용할 수 있습니다.
서명 외관
기본적으로 서명은 보이지 않습니다. 가시적 서명 위젯을 생성하려면:
php
use Yeeefang\TcpdfNext\Security\Signature\SignatureAppearance;
$pdf = Document::create()
->setSignature($cert, SignatureLevel::PAdES_B_T, $tsa)
->setSignatureAppearance(
SignatureAppearance::visible(x: 20, y: 250, w: 80, h: 30)
)
->addPage()
->cell(0, 10, 'Document with visible signature')
->save('visible-signature.pdf');명시적으로 보이지 않는 서명의 경우:
php
$pdf->setSignatureAppearance(SignatureAppearance::invisible());알고리즘 및 메서드 참조
phpseclib3을 통한 서명 알고리즘: RSA PKCS#1 v1.5 (기본값, 가장 넓은 호환성) 및 RSASSA-PSS (더 강력한 패딩, 새로운 배포에 권장).
php
$pdf->setSignature(
CertificateInfo $cert, // 인증서 및 개인 키
SignatureLevel $level, // B-B, B-T, B-LT, 또는 B-LTA
?TsaClient $tsa = null, // B-T, B-LT, B-LTA에 필수
);체이닝을 위해 static을 반환합니다. 서명은 save() 또는 output() 중에 적용됩니다.