콘텐츠로 이동

문제 해결: 서명 및 타임스탬프 실패

이 항목들은 엔진이 NextPDF\Exception\SignatureExceptionNextPDF\Security\Signature\Exception\SignatureLevelUnreachableException으로 발생시키는 서명 실패를 다룹니다. 각 항목은 정확한 팩터리 메서드 또는 클래스를 명시하므로, 원인을 추론하지 않고 메시지와 getContext()로 확인할 수 있습니다.

표현상 주의할 점: 엔진은 서명이 유효하다거나 문서가 보호된다는 것을 보증하지 않습니다. 엔진은 감지한 실패를 보고합니다. 각 해결책은 보고된 원인을 제거하기 위한 단계로 보십시오.

항목: PAdES 레벨 “B-LT” 또는 “B-LTA”를 생성할 수 없음

섹션 제목: “항목: PAdES 레벨 “B-LT” 또는 “B-LTA”를 생성할 수 없음”
  • 증상. SignatureException이며, 메시지는 nextpdf/enterprise package is required for B-LT/B-LTA signatures로 끝납니다.
  • 가능한 원인. 장기 검증 기능 제공자가 없습니다. B-LT 및 B-LTA는 폐기 자료와 보관용 타임스탬프를 포함합니다. 해당 제공자는 nextpdf/enterprise에 포함되어 있습니다.
  • 증거 / 진단. 팩터리 SignatureException::ltvCapabilityMissing()이 이 정확한 메시지를 생성합니다. getContext()signature_level에 시도한 레벨을 담아 반환합니다.
  • 해결책.
    1. 제공자를 설치하십시오. composer require nextpdf/enterprise를 실행합니다.
    2. 서명 호출을 다시 실행하십시오.
    3. 제공자를 설치할 수 없는 경우, 대신 core 패키지가 생성하는 B-B 또는 B-T를 요청하십시오.
  • 관련. 예외 참조.

항목: 서명 레벨에 도달할 수 없어 호출이 거부됨

섹션 제목: “항목: 서명 레벨에 도달할 수 없어 호출이 거부됨”
  • 증상. SignatureLevelUnreachableException이며, PAdES level "<x>" is unreachable (highest achievable: "<y>") 형식의 메시지를 동반합니다.
  • 가능한 원인. 요청된 적합성 레벨에는 서명 시점에 사용할 수 없는 인프라가 필요합니다. 대개 B-T 이상에 필요한 타임스탬프 기관입니다. 엔진은 안전 우선으로 실패합니다(fail closed). 조용히 다운그레이드한 뒤 더 높은 레벨을 표방하지 않습니다.
  • 증거 / 진단. getContext()requestedLevel, highestAchievableLevel, 그리고 reason을 반환합니다. reason 필드는 인프라 격차를 명시합니다. 이는 충족하지 못하는 레벨을 주장하는 문서가 만들어지는 것을 막기 위해 도입된 fail-closed 기본 동작입니다.
  • 해결책.
    1. 누락된 인프라를 식별하려면 reason 필드를 읽으십시오.
    2. 누락된 구성 요소를 제공하십시오. 예를 들어 타임스탬프 기관을 구성한 뒤 호출을 다시 실행합니다.
    3. 의도적으로 더 낮은 레벨을 허용하려면 allowDegradation: truePadesOrchestrator에 전달하십시오. 그러면 호출은 highestAchievableLevel을 생성하고 실제로 생성한 레벨을 보고합니다.
  • 관련. 암호화 및 권한.

항목: 타임스탬프 기관 클라이언트가 필요하지만 없음

섹션 제목: “항목: 타임스탬프 기관 클라이언트가 필요하지만 없음”
  • 증상. SignatureException이며, 메시지는 TSA client is required for level <x> but none was provided로 끝납니다.
  • 가능한 원인. B-T, B-LT 또는 B-LTA 요청에는 타임스탬프 기관 클라이언트가 필요하지만, 오케스트레이터에 연결되어 있지 않습니다.
  • 증거 / 진단. 팩터리 SignatureException::tsaRequired()가 이 메시지를 생성합니다. getContext()는 시도한 signature_level을 담고 있습니다.
  • 해결책.
    1. 타임스탬프 기관 클라이언트를 구성하여 오케스트레이터에 전달하십시오.
    2. 호출을 다시 실행하십시오.
    3. 타임스탬프가 필요하지 않은 레벨을 생성하려면 B-B를 요청하십시오.
  • 관련. 예외 참조.

항목: 타임스탬프 기관 엔드포인트 URL이 비어 있음

섹션 제목: “항목: 타임스탬프 기관 엔드포인트 URL이 비어 있음”
  • 증상. SignatureException이며, 메시지는 TSA endpoint URL is empty로 끝납니다.
  • 가능한 원인. 타임스탬프 기관 클라이언트가 빈 엔드포인트 URL로 생성되었습니다.
  • 증거 / 진단. 팩터리 SignatureException::tsaUrlEmpty()가 이 메시지를 생성합니다. 이는 네트워크 장애가 아니라 구성 결함입니다.
  • 해결책.
    1. 타임스탬프 기관 클라이언트에 비어 있지 않은 엔드포인트 URL을 설정하십시오. 예: https://timestamp.example.com/tsa입니다.
    2. 요청된 레벨에서 타임스탬프가 필요하지 않은 경우, 타임스탬프 기관 클라이언트 연결을 제거하십시오.
    3. 호출을 다시 실행하십시오.
  • 관련. 예외 참조.

항목: 버퍼에 서명 자리표시자가 없음

섹션 제목: “항목: 버퍼에 서명 자리표시자가 없음”
  • 증상. SignatureException이며, 메시지는 no /Contents <…> field found in PDF buffer (signature placeholder missing)로 끝납니다.
  • 가능한 원인. 서명 단계가 예약된 서명 컨테이너가 없는 버퍼를 대상으로 실행되어, 서명을 기록할 위치가 없습니다.
  • 증거 / 진단. 팩터리 SignatureException::signatureContentsNotFound()가 이 메시지를 생성합니다.
  • 해결책.
    1. 서명 단계가 실행되기 전에 서명 필드와 해당 자리표시자가 기록되었는지 확인하십시오.
    2. 서명이 시작될 때 자리표시자가 존재하도록 파이프라인을 다시 실행하십시오.
  • 관련. 예외 참조.

항목: 폐기 상태를 알 수 없음 (OCSP 응답자가 거부함)

섹션 제목: “항목: 폐기 상태를 알 수 없음 (OCSP 응답자가 거부함)”
  • 증상. SignatureException이며, 메시지는 OCSP responder returned non-successful OCSPResponseStatus "<status>"로 끝납니다.
  • 가능한 원인. OCSP 응답자가 successful 상태를 반환하지 않았으므로 폐기 주장을 생성하지 않았습니다. 엔진은 소스에서 인용하는 RFC 6960 §4.2.1을 따릅니다. 내용이 채워진 응답 본문은 successful (0) 상태에서만 허용됩니다. 엔진은 거부된 응답을 신뢰 긍정 결과로 취급하지 않습니다.
  • 증거 / 진단. 팩터리 SignatureException::nonSuccessfulOcspResponseStatus()가 이 메시지를 생성하고 보고된 상태를 명시합니다. 예: tryLater 또는 internalError입니다. 예약되었거나 알 수 없는 상태 바이트는 대신 SignatureException::reservedOcspResponseStatus()를 생성합니다.
  • 해결책.
    1. 메시지에서 상태를 식별하십시오. tryLater와 같은 일시적인 상태의 경우, 나중에 폐기 가져오기를 다시 시도하십시오.
    2. 상태가 unauthorized 또는 malformedRequest인 경우, OCSP 요청 URL과 응답자가 기대하는 인증서를 확인하십시오.
    3. B-LT 또는 B-LTA 아티팩트를 얻기 위해 이 실패를 억제하지 마십시오. 폐기 주장은 해당 레벨의 일부입니다.
  • 관련. 예외 참조.

항목: 인증서 체인 항목 디코딩 실패

섹션 제목: “항목: 인증서 체인 항목 디코딩 실패”
  • 증상. SignatureException이며, 메시지는 failed to base64-decode PEM body — input is not valid PEM로 끝납니다.
  • 가능한 원인. 인증서 체인 항목이 유효한 PEM이 아닙니다. 일반적으로 잘렸거나, 불필요한 문자가 있거나, PEM이 필요한 위치에 바이너리 DER 블롭이 제공된 경우입니다.
  • 증거 / 진단. 팩터리 SignatureException::pemDecodingFailed()가 체인을 조립하는 중에 이 메시지를 생성합니다.
  • 해결책.
    1. 각 체인 인증서에 불필요한 문자나 잘림이 있는지 검사하십시오.
    2. 영향을 받은 인증서를 PEM 형식으로 다시 내보내십시오.
    3. 서명 호출을 다시 실행하십시오.
  • 관련. 암호화 및 권한.

항목: 개인 키 유형이 알고리즘과 일치하지 않음

섹션 제목: “항목: 개인 키 유형이 알고리즘과 일치하지 않음”
  • 증상. SignatureException이며, 메시지는 expected private key of type "<x>" for the configured algorithm but got "<y>"로 끝납니다.
  • 가능한 원인. 로드된 개인 키가 구성된 서명 알고리즘과 일치하지 않습니다. 예를 들어 ECDSA를 선택했는데 RSA 키를 사용한 경우입니다.
  • 증거 / 진단. 팩터리 SignatureException::unexpectedKeyType()가 이 메시지를 생성하고 기대한 키 클래스와 실제 키 클래스를 모두 명시합니다.
  • 해결책.
    1. 인증서와 키 쌍이 선택한 알고리즘과 일치하는지 확인하십시오.
    2. 알고리즘 선택을 키에 맞게 변경하거나, 알고리즘에 맞는 키를 로드하십시오.
    3. 서명 호출을 다시 실행하십시오.
  • 관련. 예외 참조.

항목: Ed25519 키 또는 서명 자료가 잘못된 형식임

섹션 제목: “항목: Ed25519 키 또는 서명 자료가 잘못된 형식임”
  • 증상. SignatureException이며, 메시지 끝부분에 Ed25519 길이 불일치가 명시됩니다. 예: Ed25519 signature length <n> ≠ expected 64 bytes, 또는 Ed25519 round-trip self-verify failed입니다.
  • 가능한 원인. 런타임 암호화 빌드가 길이가 잘못된 키 또는 서명 자료를 반환했거나, 새로 생성한 서명이 자체 공개 키로 검증되지 않았습니다. 엔진은 소스에서 RFC 8032 §3.4를 인용하며, 이는 분리된 Ed25519 서명을 64 바이트로 고정합니다. 엔진은 자체 검증할 수 없는 자료를 내보내지 않고 중단합니다.
  • 증거 / 진단. 관련 팩터리는 SignatureException::ed25519SignatureMalformed(), ::ed25519RoundTripVerifyFailed(), ::ed25519KeyParseFailed(), ::ed25519SeedInvalid(), ::ed25519SecretKeyMalformed(), 그리고 ::ed25519PublicKeyInvalid()입니다. 각 팩터리는 관찰된 길이를 명시합니다.
  • 해결책.
    1. libsodium PHP 확장을 다시 설치하십시오. 축소되었거나 손상된 빌드는 길이가 잘못된 자료의 문서화된 원인입니다.
    2. 키가 Ed25519 키이고 OpenSSL이 1.1.1 이상인지 확인하십시오.
    3. 서명 호출을 다시 실행하십시오.
  • 관련. 예외 참조.

항목: 보관용 타임스탬프 딕셔너리가 출력되지 않음

섹션 제목: “항목: 보관용 타임스탬프 딕셔너리가 출력되지 않음”
  • 증상. SignatureException이며, 메시지는 no /Type /DocTimeStamp dictionary was emitted into the PDF buffer로 끝납니다.
  • 가능한 원인. B-LTA 보관 루프가 실행되었지만 문서 타임스탬프 딕셔너리가 버퍼에 도달하지 못해, 아티팩트가 절반만 기록된 B-LTA가 됩니다. 엔진은 이를 반환하지 않습니다.
  • 증거 / 진단. 팩터리 SignatureException::documentTimestampNotEmitted()가 이 메시지를 생성합니다. 이는 마무리 시점에 발생하는 사후 조건 실패입니다.
  • 해결책.
    1. 출력을 폐기된 것으로 취급하십시오. 부분 아티팩트를 배포하지 마십시오.
    2. 도달 가능한 타임스탬프 기관과 함께 B-LTA 파이프라인을 다시 실행하십시오.
    3. 실패가 반복되면, 결함 보고에 사용할 수 있도록 getContext()와 연결된 이전 예외를 함께 캡처하십시오.
  • 관련. 예외 참조.
  • 이 팩터리들은 사용 가능한 경우에만 cert_info를 주체 또는 지문으로 설정합니다. 기능 및 구성 실패의 경우 빈 cert_info는 정상입니다.
  • 구성된 HTTP 클라이언트가 없는 B-LT 또는 B-LTA 요청은 SignatureException::httpClientMissing()를 발생시킵니다. 폐기 가져오기에는 오케스트레이터에 전달된 PSR-18 클라이언트가 필요합니다.
  • HSM 기반 인증서에 서명자 구현이 없으면 SignatureException::hsmSignerMissing()가 발생합니다. 서명하기 전에 인증서에 서명자를 연결하십시오.

용어집: PAdES 레벨 · 폐기 주장