Jak dodać podpisy zabezpieczające PDF w Python

Jak dodać podpisy zabezpieczające PDF w Python

Aspose.PDF FOSS dla Python zawiera wykrywacz kompromitacji podpisu, który sprawdza już podpisany plik PDF pod kątem określonego wzorca manipulacji: znaczące bajty dołączone po zakresie bajtów objętym podpisem, ryzyko unikalne dla plików PDF aktualizowanych przyrostowo. Ten przewodnik dodaje to sprawdzenie do przepływu pracy Python przy użyciu klas SignaturesCompromiseDetector i CompromiseCheckResult. Tworzenie lub stosowanie nowych podpisów cyfrowych jest osobną częścią biblioteki i nie jest tutaj omówione. Biblioteka jest instalowana poleceniem podanym poniżej.

Przewodnik krok po kroku

Krok 1: Zainstaluj pakiet

Zainstaluj pakiet 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 .

Zweryfikuj instalację, importując SignaturesCompromiseDetector i wyświetlając komunikat potwierdzający:

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

Krok 2: Zaimportuj wymagane klasy

from aspose_pdf import CompromiseCheckResult, SignaturesCompromiseDetector

Krok 3: Przygotuj obiekt udostępniający listę podpisów

SignaturesCompromiseDetector nie parsuje samego pliku PDF — jego konstruktor akceptuje dowolny obiekt, który udostępnia atrybut signatures: listę wpisów podpisów, z których każdy zawiera valid, byte_range i reference_data. PdfSignature — prosta, bezpośrednio konstruowalna klasa — pasuje do tego kształtu, więc jest przydatna do obserwacji, jak zachowuje się sprawdzanie, zanim podłączysz je do własnego obiektu dokumentu:

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])

Zamień signed_document na własny obiekt dokumentu, gdy udostępnia on listę signatures w tym samym kształcie — dowolny obiekt z tym atrybutem działa.


Krok 4: Uruchom sprawdzenie kompromisu

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() przechodzi przez każdy podpis w signed_document.signatures, szukając niepodpisanej zawartości dopisanej po zakresie bajtów podpisanego przez każdy podpis. CompromiseCheckResult podsumowuje wynik: compromised i has_compromised_signatures raportują tę samą wartość logiczną pod dwiema nazwami, signatures_coverage podaje liczbę sprawdzonych podpisów, a reasons wymienia czytelną dla człowieka interpretację każdego wykrytego problemu.


Krok 5: Obsłuż dokument bez podpisów

Pusta lub brakująca lista signatures nie jest warunkiem błędu — jest raportowana tak samo jak dokument bez niczego do sprawdzenia:

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"]

Przekazanie SignaturesCompromiseDetector(None) — domyślnej wartości konstruktora — zachowuje się tak samo.

Typowe problemy i rozwiązania

compromised is False dla PDF-a, o którym wiesz, że został edytowany po podpisaniu

SignaturesCompromiseDetector szuka konkretnie niepodpisanych bajtów dołączonych po zakresie bajtów podpisu — wzorzec typowy dla naiwnych manipulacji przyrostowych. Nie wykonuje pełnej kryptograficznej weryfikacji podpisu. W tym celu wywołaj validate() na pojedynczym obiekcie PdfSignature.

compromised and has_compromised_signatures wydają się redundantne

To ta sama wartość: compromised jest wyliczoną właściwością, która zwraca has_compromised_signatures. Użyj tej nazwy, która lepiej pasuje w Twoim kodzie.

Nie jest zgłaszany żaden wyjątek, gdy dokument nie ma signatures atrybutu w ogóle

SignaturesCompromiseDetector traktuje dokument bez signatures atrybutu, lub document=None, tak samo jak dokument niepodpisany — check() zwraca wynik z has_compromised_signatures=False i reasons=["unsigned document"] zamiast podnosić błąd.

Nieprawidłowy PdfSignature nie zostaje oznaczony

check() pomija każdy podpis, którego byte_range nie jest listą czteroelementową, lub którego reference_data nie jest bytes/bytearray, zamiast podnosić błąd lub zgłaszać go jako skompromitowany. Podpis z niewłaściwym kształtem jest cicho wykluczany z kontroli, nie jest oznaczany.

Mylenie tego detektora z tworzeniem podpisu

SignaturesCompromiseDetector i CompromiseCheckResult jedynie sprawdzają podpisy, które już istnieją w dokumencie — nie mają sposobu na stworzenie, zastosowanie ani osadzenie nowego podpisu.

Najczęściej zadawane pytania

Co dokładnie liczy się jako “compromised” tutaj?

Znaczące, niebiałe bajty dołączone do pliku PDF po zakresie bajtów podpisu — z dwoma wyjątkami, które detektor już uwzględnia: późniejszy podpis lub znacznik czasu, który sam obejmuje te bajty, oraz przyrostowa aktualizacja, która dodaje jedynie materiały weryfikacyjne (takie jak /DSS) bez nakładania nowej zawartości, takiej jak adnotacje.

Czy to weryfikuje kryptograficzną ważność samego podpisu?

Nie. SignaturesCompromiseDetector sprawdza wzorce manipulacji wokół zakresu podpisanych bajtów. Kryptograficzna ważność jest osobnym sprawdzeniem, dostępnym przez PdfSignature.validate().

Co signatures_coverage mi mówi?

Liczba podpisów, które sprawdzenie faktycznie przeanalizowało w przekazanym dokumencie — przydatna do potwierdzenia, że detektor zobaczył oczekiwane podpisy, zanim uwierzysz w czysty wynik.

Czy mogę sprawdzić dokument z wieloma podpisami jednocześnie?

Tak. check() iteruje każdy wpis w signed_document.signatures i zwraca jedną zbiorczą CompromiseCheckResult obejmującą wszystkie.

Czy w normalnym użyciu muszę samodzielnie tworzyć obiekty PdfSignature?

Nie — konstrukcja PdfSignature w kroku 3 służy bezpośredniemu badaniu zachowania detektora. W rzeczywistym przepływie pracy przekazuj dowolny obiekt, który już generuje Twój kod ładowania dokumentu, pod warunkiem że udostępnia listę signatures wpisów w kształcie PdfSignature.

Zobacz także

 Polski