Comment ajouter des signatures de sécurité PDF dans Python
Aspose.PDF FOSS pour Python inclut un détecteur de compromission de signature qui examine un PDF déjà signé à la recherche d’un motif de falsification spécifique: des octets significatifs ajoutés après la plage d’octets signée d’une signature, un risque propre aux fichiers PDF mis à jour de façon incrémentale. Ce guide ajoute cette vérification à un flux de travail Python en utilisant les classes SignaturesCompromiseDetector et CompromiseCheckResult. La création ou l’application de nouvelles signatures numériques constitue une autre partie de la bibliothèque et n’est pas abordée ici. La bibliothèque s’installe avec la commande ci-dessous.
Guide étape par étape
Étape 1: installer le paquet
Installez le paquet FOSS Aspose.PDF:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .Vérifiez l’installation en important SignaturesCompromiseDetector et en affichant un message de confirmation:
from aspose_pdf import SignaturesCompromiseDetector
print("aspose-pdf-foss-for-python is ready.")Étape 2: Importer les classes requises
from aspose_pdf import CompromiseCheckResult, SignaturesCompromiseDetectorÉtape 3: Préparer un objet exposant une liste de signatures
SignaturesCompromiseDetector ne parse pas un PDF lui-même — son constructeur accepte tout objet qui expose un attribut signatures: une liste d’entrées de signature, chacune contenant valid, byte_range et reference_data. PdfSignature — une classe simple, directement constructible — correspond à cette forme, ce qui est utile pour voir comment la vérification se comporte avant de la connecter à votre propre objet document:
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])Remplacez signed_document par votre propre objet document dès qu’il expose une liste signatures de la même forme — tout objet possédant cet attribut fonctionne.
Étape 4: Exécuter le Compromise Check
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() parcourt chaque signature dans signed_document.signatures, à la recherche de contenu non signé ajouté après la plage d’octets signée de chaque signature. Un CompromiseCheckResult résume le résultat: compromised et has_compromised_signatures rapportent le même booléen sous deux noms, signatures_coverage indique combien de signatures ont été examinées, et reasons répertorie une explication lisible par l’homme pour chaque problème trouvé.
Étape 5: Gérer un document sans signatures
Une liste signatures vide ou manquante n’est pas une condition d’erreur — elle est signalée de la même façon qu’un document sans rien à vérifier:
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"]Passer SignaturesCompromiseDetector(None) — la valeur par défaut du constructeur — se comporte de la même manière.
Problèmes courants et solutions
compromised is False pour un PDF que vous savez avoir été modifié après la signature
SignaturesCompromiseDetector recherche spécifiquement les octets non signés ajoutés après la plage d’octets signés d’une signature — un schéma typique de falsification naïve par mise à jour incrémentielle. Il ne réalise pas de vérification complète de la signature cryptographique. Pour cela, appelez validate() sur l’objet PdfSignature individuel.
compromised and has_compromised_signatures semble redondant
Ils ont la même valeur: compromised est une propriété calculée qui renvoie has_compromised_signatures. Utilisez le nom qui s’intègre le mieux dans votre code.
Aucune exception n’est levée lorsque le document n’a pas de signatures aucun attribut
SignaturesCompromiseDetector considère un document sans attribut signatures, ou document=None, de la même manière qu’un document non signé — check() renvoie un résultat avec has_compromised_signatures=False et reasons=["unsigned document"] au lieu de lever une exception.
Un malformé PdfSignature n’est pas signalé
check() ignore toute signature dont le byte_range n’est pas une liste de 4 éléments, ou dont le reference_data n’est pas bytes/bytearray, plutôt que de lever une exception ou de la signaler comme compromise. Une signature construite avec la mauvaise forme est silencieusement exclue du contrôle, sans être signalée.
Confondre ce détecteur avec la création de signature
SignaturesCompromiseDetector et CompromiseCheckResult n’inspectent que les signatures déjà présentes sur un document — ils n’ont aucun moyen de créer, appliquer ou intégrer une nouvelle signature.
Foire aux questions
Qu’est-ce qui est exactement considéré comme « compromis » ici?
Octets significatifs, non blancs, ajoutés au PDF après la plage d’octets signée d’une signature — avec deux exceptions déjà prises en compte par le détecteur: une signature ou un horodatage ultérieur qui couvre eux-mêmes ces octets, et une mise à jour incrémentielle qui n’ajoute que du matériel de validation (tel qu’un /DSS) sans superposer de nouveau contenu comme des annotations.
Cela vérifie-t-il la validité cryptographique de la signature elle-même?
Non. SignaturesCompromiseDetector recherche des modèles de falsification autour de la plage d’octets signés. La validité cryptographique est une vérification distincte, disponible via PdfSignature.validate().
Que me dit signatures_coverage?
Le nombre de signatures que la vérification a réellement examinées dans le document fourni — utile pour confirmer que le détecteur a vu les signatures attendues avant de faire confiance à un résultat propre.
Puis-je vérifier un document contenant plusieurs signatures en une seule fois?
Oui. check() parcourt chaque entrée dans signed_document.signatures et renvoie un CompromiseCheckResult agrégé couvrant toutes les entrées.
Dois-je construire moi-même des objets PdfSignature en utilisation normale?
Non — la construction de PdfSignature à l’étape3 sert à explorer directement le comportement du détecteur. Dans un flux de travail réel, transmettez simplement l’objet que votre code de chargement de documents produit déjà, tant qu’il expose une liste signatures d’entrées de forme PdfSignature.