콘텐츠로 이동
getnextpdf.com

Enterprise 에디션

NextPDF Enterprise 빠른 시작

이 튜토리얼은 빈 프로젝트에서 시작해 두 가지 동작하는 Enterprise 결과에 이르도록 안내합니다. 먼저 기존 서명된 PDF를 검증하고 그 MainIndication을 읽습니다. 그런 다음 장기 생산자로 서명된 문서를 PAdES B-LT로 끌어올립니다. 모든 단계는 예상되는 정확한 출력이나 예외를 보여줍니다. NextPDF는 인증이 아니라 기능을 문서화합니다: PAdES나 eIDAS 인증을 보유하지 않으며, 어떠한 인증도 부여하지 않습니다.

이 기능은 NextPDF Enterprise (nextpdf/enterprise)에서 제공되며 Enterprise 등급 라이선스 봉투로 활성화됩니다. 해당 권한이 없는 배포는 이 기능의 클래스를 로드하지 않습니다. 에디션을 비교하고 라이선스를 받으세요.

  • Composer가 비공개 NextPDF 저장소용으로 구성되어 있어야 합니다. 먼저 설치 및 인증을 따르세요.
  • Enterprise 라이선스 봉투를 보유하고 있으며, 이는 app.getnextpdf.com 계정에서 다운로드한 것입니다. 라이선싱 및 활성화에서 봉투가 무엇이며 어디에 두는지 설명합니다.
  • 3단계에서는 검증할 서명된 PDF가 필요합니다. B-LT 부분에서는 서명자 인증서와 OCSP/CRL 응답자에 대한 네트워크 접근도 필요합니다.

Enterprise 패키지를 요구하세요. 이 패키지는 nextpdf/corenextpdf/pro에 의존하므로 Composer가 전체 스택을 가져옵니다:

Terminal window
composer require nextpdf/enterprise
composer show nextpdf/enterprise

composer show가 패키지와 그 버전을 출력하면 설치가 성공한 것입니다. 이제 서명된 라이선스 봉투를 배포가 로드하는 위치에 라이선싱 및 활성화가 설명하는 대로 정확히 배치하세요. 패키지만 설치한다고 Enterprise 기능이 부여되지는 않습니다; 활성화된 라이선스가 에디션을 선택합니다.

라이선스가 무엇을 부여하는지 권한 평가기에 물어보세요. 부트스트랩은 활성화 과정에서 검증된 NextPDF\Enterprise\Licensing\LicenseKey를 획득합니다; 이를 전달하세요:

<?php
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Licensing\EntitlementEvaluator;
use NextPDF\Enterprise\Licensing\LicenseKey;
/** @var LicenseKey|null $license The verified license from activation. */
$result = (new EntitlementEvaluator())->evaluate($license);
echo 'status: ' . $result->status->value . PHP_EOL;
echo 'edition: ' . ($result->edition?->value ?? 'none') . PHP_EOL;
echo 'runtime: ' . ($result->runtimeAllowed ? 'allowed' : 'disabled') . PHP_EOL;

활성 Enterprise 라이선스가 있으면 다음과 같이 표시됩니다:

status: active
edition: enterprise
runtime: allowed

이 단계 뒤의 메서드:

public function evaluate(?LicenseKey $license, ?DateTimeImmutable $now = null): EntitlementResult

던지거나 실패하는 경우: 절대 예외를 던지지 않습니다. 누락된 라이선스는 EntitlementStatus::NoLicenseruntimeAllowed false를 가진 fail-closed EntitlementResult를 반환합니다(4단계 참조).

서명된 PDF에서 서명을 추출한 다음 기본 AdES 검증을 실행하세요. 엔진은 ETSI EN 319 102-1의 검증 레벨을 구현합니다; validateBasic()은 절 5.2 흐름입니다 — 구조, 다이제스트, 서명 암호, 그리고 인증서 체인:

<?php
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;
use NextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractor;
use NextPDF\Enterprise\Signature\SignatureExtractor;
$pdf = file_get_contents(__DIR__ . '/contract-signed.pdf');
if ($pdf === false) {
throw new RuntimeException('Could not read contract-signed.pdf');
}
$signatures = (new SignatureExtractor())->extract($pdf);
if ($signatures === []) {
throw new RuntimeException('The PDF carries no signature dictionary.');
}
$engine = new AdESValidationEngine(extractor: new CmsSignatureDataExtractor());
$report = $engine->validateBasic(
$signatures[0]['signedBytes'], // the exact /ByteRange-covered bytes
$signatures[0]['contents'], // the DER CMS SignedData from /Contents
);
echo $report->mainIndication->name . PHP_EOL;
echo ($report->subIndication?->name ?? '(none)') . PHP_EOL;

이 예제에서 구성된 기본 구조, 다이제스트, 암호, 체인 검사를 통과하는 정형(well-formed) 서명의 경우 다음과 같이 표시됩니다:

TOTAL_PASSED
(none)

MainIndication은 정확히 세 가지 경우를 가집니다: TOTAL_PASSED, TOTAL_FAILED, 그리고 INDETERMINATE. 엔진은 fail-closed입니다: 확실히 확립할 수 없는 검사는 조용한 통과가 아니라 INDETERMINATE를 산출합니다. 여기서의 통과는 이 엔진의 검사에 따른 검증 결과이며, 신뢰나 인증 진술이 아닙니다 — 신뢰 앵커와 장기 증거는 검증 페이지의 더 깊은 레벨에 속합니다.

public function extract(string $pdfData): array

던지거나 실패하는 경우: 입력이 유효한 PDF가 아니면 InvalidArgumentException. 잘못된 /ByteRange/Contents는 긍정 결과가 아니라 빈 문자열(fail-closed)을 산출합니다.

public function validateBasic(string $signedData, string $signature): ValidationReport

던지거나 실패하는 경우: 검증 실패 시 절대 예외를 던지지 않습니다. 모든 결함은 HASH_FAILURESIG_CRYPTO_FAILURE 같은 ValidationReport 표시로 매핑됩니다.

이제 방금 서명된 문서를 B-LT로 업그레이드하세요. 장기 생산자는 인증서 체인과 OCSP/CRL 증거를 수집하고 문서 보안 저장소(DSS)를 작성합니다. 이는 서명 페이지에 설명된 서명 패스를 이어가며, 출력 버퍼, 객체 레지스트리, 서명 /Contents hex를 제공합니다:

use NextPDF\Enterprise\Security\Ltv\LtvManager;
use NextPDF\Security\Signature\CertificateInfo;
use NextPDF\Security\Signature\SignatureLevel;
$certInfo = CertificateInfo::fromPkcs12('/secure/signer.p12', $p12Password);
// $httpClient is any PSR-18 client; it fetches OCSP responses and CRLs.
$ltv = new LtvManager($certInfo, $httpClient, level: SignatureLevel::PAdES_B_LT);
// $buffer, $registry, and $signatureContentsHex come from the signing pass.
$dssObjectNumber = $ltv->enableLtv($buffer, $registry, $signatureContentsHex);

반환값은 문서 카탈로그의 /DSS 항목을 위한 DSS 객체 번호입니다. 생산자는 기본적으로 엄격한(strict) 폐기 강제를 적용합니다: 폐기 자료가 누락되면 속 빈 “B-LT” 파일을 조용히 발행하는 대신 예외를 발생시킵니다.

public function enableLtv(BinaryBuffer $buffer, ObjectRegistry $registry, string $signatureContentsHex): int

던지거나 실패하는 경우: 체인 검증이 실패하거나, 인증서가 폐기되었거나, 엄격한 기본값에서 폐기 자료가 누락된 경우 NextPDF\Enterprise\Security\Ltv\LtvException.

status: no_license — 봉투가 로드되지 않음

섹션 제목: “status: no_license — 봉투가 로드되지 않음”

2단계가 status: no_licenseruntime: disabled를 출력하고, 결과에 경고 No license configured. Enterprise runtime is disabled. Install a license or purchase one at https://nextpdf.dev/pricing가 담깁니다. 그러면 권한 게이트가 걸린 호출은 코드 SPEC-LIC-001과 함께 NextPDF\Accelerator\Exception\SpectrumAuthenticationException을 던집니다. 예: Capability '...' requires a valid license. 해결: 라이선싱 및 활성화에 따라 봉투를 배치하고 활성화한 다음 2단계를 다시 실행하세요.

InvalidArgumentException: Input does not start with %PDF header

섹션 제목: “InvalidArgumentException: Input does not start with %PDF header”

SignatureExtractor::extract()가 PDF가 아닌 것을 받았습니다 — 잘못된 경로, 빈 읽기, 또는 압축된 다운로드. 로드한 파일을 확인하세요. 빈 $signatures 목록은 다릅니다: 파일은 PDF이지만 /Type /Sig 딕셔너리가 없으므로 검증할 것이 없습니다.

LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0

섹션 제목: “LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0”

enableLtv()가 체인 인증서에 대한 OCSP 응답이나 CRL을 획득하지 못했고, 엄격한 기본값은 증거 없이 B-LT 주장을 작성하기를 거부합니다. 호스트에서 응답자 도달성을 확인하거나, 경고 전용 실행을 명시적으로 수용하는 경우에만 enforcementMode: RevocationEnforcementMode::PERMISSIVE를 전달하세요 — 누락된 폐기 증거를 명시적으로 수용하고 문서화하지 않는 한, 그런 출력을 프로덕션이나 컴플라이언스 워크플로에 대해 절대 B-LT로 라벨링하지 마세요. 관련: TSA 클라이언트 없이 B-LTA를 요청하면 LtvException: TSA client required for document timestamps로 실패합니다.