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, SignaturesCompromiseDetector3단계: 서명 목록을 노출하는 객체 준비
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 findingscheck()는 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 항목을 제공하기만 하면 됩니다.