Skip to content

디지털 서명 (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
TsaClientRFC 3161 타임스탬프 기관 클라이언트
SignatureAppearance가시적 또는 비가시적 서명 위젯
OcspClientRFC 6960 온라인 폐지 확인
CrlFetcherRFC 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() 중에 적용됩니다.

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