콘텐츠로 이동
getnextpdf.com

서명된 계약 워크플로

Spec: ETSI EN 319 142-2, §5.1Spec: ISO 32000-2:2020, §12.8

서명된 계약은 “서명이 붙은 PDF”가 아닙니다. 서명이 올바른 바이트를 보호하도록 준비되고, 의무 수준에 맞는 수준으로 서명된 문서입니다. 서명 인증서가 만료된 후에도 계속 검증될 수 있도록 패키징됩니다. 이 페이지는 빈 문서에서 오래 지속되는 계약에 이르기까지 그 시나리오를 따라갑니다. 현재 엔진이 어떤 단계를 배선했고 어떤 단계를 동결된 표면으로 노출하는지도 솔직하게 밝힙니다.

서명한 당일에는 검증되지만 3년 후 분쟁에서 실패하는 계약은 누군가가 그것을 신뢰했기 때문에 서명이 아예 없는 것보다 더 나쁩니다. 실패의 원인이 암호화인 경우는 드뭅니다. 대개 타임스탬프 누락이나 폐기 증거 누락이며, 서명자가 떠난 지 한참 후에 판가름 납니다.

서명 의무 수준을 미리 선택하고 그 의무에 필요한 증거를 서명 시점에 생산하는 것이, 시간이 지나도 버티는 계약과 조용히 훼손되는 계약을 가르는 차이입니다. 이것은 분쟁이 생길 때마다 다시 발견할 것이 아니라 워크플로 안에서 한 번 내려야 할 결정입니다.

  • 준비한 다음 서명하십시오. 서명은 계산 대상인 바이트 범위만 정확히 보호합니다. 나중에 추가될 개정 사항까지 고려해, 문서가 최종본이라는 결정은 서명 후가 아니라 서명 전에 내리십시오.
  • 의무에 맞는 수준을 고르십시오. 그 반대가 아닙니다. PAdES는 단계적 진행을 정의합니다. 기본 서명, 타임스탬프가 찍힌 서명, 검증 자료가 내장된 서명, 그리고 무기한 보관 유효성을 위해 다시 스탬프되는 서명입니다(ETSI EN 319 142-2 §5.1).
  • 장기 유효성은 속성이 아니라 구조입니다. 이는 파일에 기록된 Document Security Store와 문서 타임스탬프입니다(ISO 32000-2:2020 §12.8).
  • 이음새를 정확하게 밝힙니다. NextPDF의 고수준 Document::setSignature()는 공개 API를 동결하지만, 서명되지 않은 파일을 내보내는 대신 빠르게 실패합니다. 배선된 경로는 더 낮은 수준의 오케스트레이터입니다. 이 페이지는 그렇지 않은 척하지 않습니다.

NextPDF는 결정메커니즘에서 분리합니다. 결정은 의무에 필요한 PAdES 수준을 고르는 것입니다. 메커니즘은 바이트가 어떻게 서명되고 검증 자료가 어떻게 운반되는지입니다. 이 둘을 하나로 취급하면 팀은 유효하지만 내구성이 없는 서명에 도달하게 됩니다.

시나리오에는 네 단계가 있습니다.

  1. Prepare the documentCompose the agreement and treat it as final. The signature will protect this exact byte range and nothing added outside it without a new revision.
  2. Choose the obligationB-B proves who. B-T adds trusted time. B-LT embeds the material to validate later. B-LTA re-stamps for indefinite validity.
  3. SignA CMS signature is embedded in the signature dictionary over the byte range; a timestamp is requested from a TSA if the level needs one.
  4. PreserveFor long-term levels, the Document Security Store and a document timestamp are written so the signature outlives its certificate.
서명된 계약 시나리오를 처음부터 끝까지 봅니다. 각 단계는 하나의 보장을 추가하며, 2 단계에서 선택하는 수준이 3 단계와 4 단계가 얼마나 많은 증거를 생산해야 하는지를 결정합니다.

수준 열거형은 실제로 존재하며, 의무를 있는 그대로 인코딩합니다. B-B는 서명자의 신원을 증명합니다. B-T는 신뢰할 수 있는 타임스탬프를 추가합니다. “언제”를 “누가”만큼 확실하게 만듭니다. B-LT는 서명 인증서가 만료된 후 서명을 검증하는 데 필요한 인증서와 폐기 응답을 내장합니다. B-LTA는 문서 타임스탬프를 추가하여 신뢰 체인을 각 타임스탬프 인증서가 만료되기 전에 다시 스탬프함으로써 무기한 연장할 수 있게 합니다. 이 열거형은 어떤 수준이 타임스탬프를 요구하고 어떤 수준이 내장 검증 자료를 요구하는지 알고 있어서, 엔진은 불가능한 조합을 오해의 소지가 있는 “서명된” 파일을 생산하는 대신 거부할 수 있습니다.

이 예제는 실제 열거형을 사용하여 결정 — 의무를 선택하는 것 — 을 보여줍니다. 배선된 서명 경로는 더 낮은 수준의 오케스트레이터입니다. 고수준 호출은 빠른 실패 동작을 명시적으로 드러내기 위해서만 보여집니다.

<?php
declare(strict_types=1);
use NextPDF\Security\Signature\SignatureLevel;
/**
* Map a business obligation to a PAdES level.
*
* The obligation drives the level, not the reverse — choosing B-B for a
* 10-year contract is a decision you do not want to make implicitly.
*/
function levelForObligation(string $obligation): SignatureLevel
{
return match ($obligation) {
// Internal sign-off, short retention, signer identity is enough.
'internal_approval' => SignatureLevel::PAdES_B_B,
// Counterparty agreement: prove the moment of signing.
'counterparty_agreement' => SignatureLevel::PAdES_B_T,
// Regulated contract that must verify after cert expiry.
'regulated_contract' => SignatureLevel::PAdES_B_LT,
// Long-lived legal record: indefinite, re-stampable validity.
'long_term_legal_record' => SignatureLevel::PAdES_B_LTA,
default => throw new \InvalidArgumentException(
"Unknown obligation: {$obligation}",
),
};
}
$level = levelForObligation('regulated_contract');
// The enum carries the obligation's implications with it.
$needsTsa = $level->requiresTimestamp(); // true for B-T+
$needsDss = $level->requiresDss(); // true for B-LT+
$needsArchive = $level->requiresDocumentTimestamp(); // true only for B-LTA

수준 객체는 레이블이 아닙니다. 의무가 무엇을 수반하는지 답해 주므로, 다운스트림 배선이 그것을 다시 도출할 필요가 없습니다.

되풀이되는 오해는 *“서명이 유효하니 끝났다.”*입니다. 현재의 유효성은 필요하지만 충분하지는 않습니다. 서명은 바이트 범위에 대해 계산됩니다. 그 범위 밖에 후속 개정에서 추가된 것은 그 서명으로 보호되지 않으며, 바로 그래서 준비가 서명보다 먼저 와야 합니다. 또 지금 검증되는 서명이라도 서명 시점에 검증 자료가 내장되지 않았다면 인증서가 만료될 때 나중에 실패할 수 있습니다. “유효함”과 “내구성 있음”은 서로 다른 보장이며, 어느 쪽이 실제로 필요한지는 의무만이 알려줍니다.

이 엔진에 특유한 관련 함정은 고수준 setSignature()가 현재 서명된 파일을 생산한다고 가정하는 것입니다. 그렇지 않습니다. 의도적으로 빠르게 실패합니다. 그 진단을 계약으로 취급하십시오.

  • Document::setSignature()는 동결된 공개 표면이지 배선된 서명자가 아닙니다. 이는 차단성 진단과 함께 빠르게 실패합니다. 서명된 PDF 대신 서명되지 않은 PDF를 결코 내보내지 않습니다. 배선된 경로는 더 낮은 수준의 2단계 오케스트레이터입니다.
  • 장기 검증 유지 관리(DSS/VRI, 상태 점검, 보관 타임스탬프 루프)는 Premium 등급 기능입니다. Core는 보관 루프를 제공하지 않습니다. 아래의 경계를 참조하십시오.
  • 서명은 정확히 자신의 바이트 범위를 보호합니다. 나중에 추가된 개정 사항은 별개입니다. 엔진은 보호 범위를 소급하여 확장하지 않습니다.
  • NextPDF는 구조를 생산하고 유지 관리하며, 판정하지는 않습니다. 서명이 신뢰되는지 여부는 검증자의 신뢰 앵커와 정책에 달려 있으며, 이는 엔진 외부에 있습니다.
  • B-LTA는 그 자체로 서명을 영원하게 만들지 않습니다. 각 타임스탬프 인증서가 만료되기 전에 다시 스탬프하는 루프가 일정대로 실행되는 경우에만 무기한 유효성을 가능하게 합니다.
  • 이 페이지는 Premium 보관 표면에 대해 동작 수준입니다. 특정 법원이나 기관의 어떠한 수용도 주장하지 않습니다.
PAdES signing and long-term validity — edition availability
EditionAvailability
Core

Core는 SignatureLevel 열거형과 동결된 Document::setSignature() 표면(빠른 실패)을 노출합니다. 배선된 더 낮은 수준의 오케스트레이터는 기본 서명을 다룹니다. 장기 보관 유지 관리는 Core에는 없습니다.

Pro

PAdES 기본 서명(B-B / B-T)을 오케스트레이터를 통해 사용할 수 있습니다.

Enterprise

B-LT / B-LTA, Document Security Store와 서명별 VRI 유지 관리, LTV 상태 점검, 그리고 무기한 유효성을 위한 문서 타임스탬프 보관 루프를 추가합니다.

  • PAdES 기본 프로파일B-B, B-T, B-LT, B-LTA를 단계적 진행으로 설명하고 선택하는 방법을 다룹니다.
  • 장기 검증 — 현재 검증되는 서명이 왜 10년 후에 실패할 수 있는지, 그리고 LTV가 어떻게 증거를 내장하는지를 다룹니다.
  • 통합 결정 가이드 — NextPDF Connect의 사람 승인 이음새를 포함하여, 어떤 생태계 패키지가 서명 워크플로에 맞는지를 다룹니다.
  • PAdES — PDF Advanced Electronic Signatures: 고급 전자 서명이 PDF에 어떻게 운반되는지를 정의하는 ETSI 프로파일 제품군입니다.
  • 바이트 범위 — 서명이 계산 대상으로 삼는 연속된 파일 바이트 구간으로, 그 밖의 콘텐츠는 해당 서명으로 보호되지 않습니다.
  • 서명 수준(B-B / B-T / B-LT / B-LTA)PAdES 진행 단계입니다. 누가 서명했는지, 언제 서명했는지, 검증 자료를 내장했는지, 그리고 무기한 보관 유효성을 위해 다시 스탬프할 수 있는지를 나타냅니다.
  • TSA — Time-Stamping Authority: 문서 상태가 주어진 UTC 시점에 존재했음을 단언하는 RFC 3161 서비스입니다.
  • DSS (Document Security Store) — 인증서가 만료된 후 서명을 검증하는 데 필요한 인증서, OCSP 응답, CRL의 파일 내 저장소입니다.
  • LTV (Long-Term Validation) — 검증 증거를 내장하고 다시 스탬프함으로써 서명을 시간이 지나도 검증 가능하게 유지하는 것입니다.
  • 빠른 실패(Fail-fast) — 조용히 잘못된 파일을 내보내는 대신, 오해의 소지가 있는 산출물 생산을 거부하고 실행 가능한 오류를 일으키는 것입니다.