Python에서 PDF 보안 서명을 추가하는 방법

Python에서 PDF 보안 서명을 추가하는 방법

Aspose.PDF FOSS for Python는 이미 서명된 PDF에서 특정 변조 패턴을 검사하는 서명 손상 감지기를 포함합니다: 서명의 서명된 바이트 범위 뒤에 의미 있는 바이트가 추가되는 경우로, 점진적으로 업데이트되는 PDF 파일에만 존재하는 위험입니다. 이 가이드는 SignaturesCompromiseDetector와 CompromiseCheckResult 클래스를 사용하여 Python 워크플로에 해당 검사를 추가합니다. 새로운 디지털 서명을 생성하거나 적용하는 것은 라이브러리의 별도 부분이며 여기서는 다루지 않습니다. 라이브러리는 아래 명령으로 설치됩니다.

단계별 가이드

1단계: 패키지 설치

Aspose.PDF FOSS 패키지를 설치합니다:

git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .

SignaturesCompromiseDetector를 임포트하고 확인 메시지를 출력하여 설치를 검증합니다:

from aspose_pdf import SignaturesCompromiseDetector
print("aspose-pdf-foss-for-python is ready.")

2단계: 필요한 클래스 가져오기

from aspose_pdf import CompromiseCheckResult, SignaturesCompromiseDetector

3단계: 서명 목록을 노출하는 객체 준비

SignaturesCompromiseDetector는 PDF를 직접 파싱하지 않습니다 — 생성자는 signatures 속성을 제공하는 모든 객체를 받아들입니다: 서명 항목들의 목록이며, 각 항목은 valid, byte_range, 및 reference_data를 포함합니다. PdfSignature — 단순하고 직접 인스턴스화 가능한 클래스 —는 그 형태와 일치하므로, 자체 문서 객체에 연결하기 전에 검사가 어떻게 동작하는지 확인하는 데 유용합니다:

from types import SimpleNamespace
from aspose_pdf import PdfSignature

with open("signed.pdf", "rb") as handle:
    pdf_bytes = handle.read()

signature = PdfSignature(
    name="Signature1",
    contents=b"...",  # PKCS#7 signed-data blob from the signature dictionary
    byte_range=[0, 1024, 1040, len(pdf_bytes) - 1040],
    reference_data=pdf_bytes,
)

signed_document = SimpleNamespace(signatures=[signature])

signed_document를 자체 문서 객체로 교체하십시오. 해당 객체가 동일한 형태의 signatures 목록을 노출하면 — 그 속성을 가진 어떤 객체든 작동합니다.


4단계: 손상 검사 실행

from aspose_pdf import SignaturesCompromiseDetector

detector = SignaturesCompromiseDetector(signed_document)
result = detector.check()

print(result.compromised)                # bool
print(result.has_compromised_signatures)  # bool -- same value as compromised
print(result.signatures_coverage)         # int -- number of signatures inspected
print(result.reasons)                     # list[str] -- human-readable findings

check()는 signed_document.signatures에 있는 모든 서명을 순회하면서, 각 서명의 서명된 바이트 범위 뒤에 추가된 서명되지 않은 내용을 찾습니다. CompromiseCheckResult는 결과를 요약합니다: compromised와 has_compromised_signatures는 동일한 불리언 값을 두 이름으로 보고하고, signatures_coverage는 검사된 서명 수를 보고하며, reasons은 발견된 각 문제에 대한 사람이 읽을 수 있는 설명을 나열합니다.


5단계: 서명이 없는 문서 처리

비어 있거나 누락된 signatures 목록은 오류 상황이 아닙니다 — 검사할 것이 없는 문서와 동일한 방식으로 보고됩니다:

from types import SimpleNamespace
from aspose_pdf import SignaturesCompromiseDetector

unsigned_document = SimpleNamespace(signatures=[])
detector = SignaturesCompromiseDetector(unsigned_document)
result = detector.check()

print(result.compromised)  # False
print(result.reasons)      # ["unsigned document"]

SignaturesCompromiseDetector(None) 를 전달하는 것 — 생성자의 기본값 — 은 동일하게 동작합니다.

일반적인 문제 및 해결 방법

compromised is False 서명 후에 편집된 것으로 알고 있는 PDF에 대해

SignaturesCompromiseDetector 은 서명의 서명된 바이트 범위 뒤에 추가된 서명되지 않은 바이트를 구체적으로 찾습니다 — 이는 순진한 증분 업데이트 변조에서 흔히 보이는 패턴입니다. 전체 암호학적 서명 검증을 수행하지 않습니다. 이를 위해서는 개별 PdfSignature 객체에 대해 validate() 을 호출하십시오.

compromised and has_compromised_signatures 불필요해 보인다

두 값은 동일합니다: compromised 은 has_compromised_signatures 을 반환하는 계산된 속성입니다. 코드에서 더 읽기 쉬운 이름을 사용하세요.

문서에 해당 항목이 없을 때 예외가 발생하지 않는다 signatures 속성이 전혀 없음

SignaturesCompromiseDetector은(는) signatures 속성이 없거나 document=None인 문서를 서명되지 않은 문서와 동일하게 취급합니다 — check()은(는) 예외를 발생시키는 대신 has_compromised_signatures=False와 reasons=["unsigned document"]를 포함한 결과를 반환합니다.

잘못된 PdfSignature 플래그되지 않는다

check()은(는) byte_range이 4요소 리스트가 아니거나 reference_data이 bytes/bytearray가 아닌 서명을 예외를 발생시키거나 손상된 것으로 보고하는 대신 건너뜁니다. 잘못된 형태로 만든 서명은 검사에서 조용히 제외되며, 플래그가 지정되지 않습니다.

이 탐지기를 서명 생성과 혼동

SignaturesCompromiseDetector와 CompromiseCheckResult은(는) 문서에 이미 존재하는 서명만 검사합니다 — 새로운 서명을 생성, 적용하거나 삽입할 방법이 없습니다.

자주 묻는 질문

여기서 정확히 무엇을 “손상된” 것으로 간주합니까?

서명의 서명된 바이트 범위 이후 PDF에 추가된 의미 있는 비공백 바이트 — 탐지기가 이미 고려하고 있는 두 가지 예외가 있습니다: 해당 바이트를 자체적으로 포함하는 후속 서명 또는 타임스탬프, 그리고 주석과 같은 새 콘텐츠를 겹치지 않고 검증 자료(예: /DSS)만 추가하는 증분 업데이트.

이것이 서명의 암호학적 유효성을 검증합니까?

아니요. SignaturesCompromiseDetector은 서명된 바이트 범위 주변의 변조 패턴을 검사합니다. 암호학적 유효성 검사는 별도의 검사이며, PdfSignature.validate()을 통해 이용할 수 있습니다.

signatures_coverage은(는) 나에게 무엇을 알려줍니까?

전달된 문서에서 검사 실제로 검토한 서명 개수 — 깨끗한 결과를 신뢰하기 전에 탐지기가 기대한 서명을 확인하는 데 유용합니다.

여러 서명이 포함된 문서를 한 번에 검사할 수 있나요?

예. check()은 signed_document.signatures의 모든 항목을 순회하며, 모두를 포괄하는 단일 집계 CompromiseCheckResult를 반환합니다.

일반적인 사용에서는 직접 PdfSignature 객체를 생성해야 합니까?

아니요 — 3단계의 PdfSignature 생성은 탐지기의 동작을 직접 탐색하기 위한 것입니다. 실제 워크플로에서는 문서 로드 코드가 이미 생성하는 객체를 그대로 전달하면 되며, 해당 객체가 signatures 리스트 형태의 PdfSignature 항목을 제공하기만 하면 됩니다.

참조

 한국어