Como adicionar assinaturas de segurança PDF em Python

Como adicionar assinaturas de segurança PDF em Python

Aspose.PDF FOSS para Python inclui um detector de comprometimento de assinatura que inspeciona um PDF já assinado em busca de um padrão específico de adulteração: bytes significativos adicionados após o intervalo de bytes assinado da assinatura, um risco exclusivo de arquivos PDF atualizados incrementalmente. Este guia adiciona essa verificação a um fluxo de trabalho Python usando as classes SignaturesCompromiseDetector e CompromiseCheckResult. Criar ou aplicar novas assinaturas digitais é uma parte separada da biblioteca e não está coberta aqui. A biblioteca é instalada com o comando abaixo.

Guia passo a passo

Etapa 1: Instalar o Pacote

Instale o pacote 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 .

Verifique a instalação importando SignaturesCompromiseDetector e imprimindo uma mensagem de confirmação:

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

Etapa 2: Importar Classes Necessárias

from aspose_pdf import CompromiseCheckResult, SignaturesCompromiseDetector

Etapa 3: Preparar um Objeto que Exponha uma Lista de Assinaturas

SignaturesCompromiseDetector não analisa um PDF por si só — seu construtor aceita qualquer objeto que exponha um atributo signatures: uma lista de entradas de assinatura, cada uma contendo valid, byte_range e reference_data. PdfSignature — uma classe simples, diretamente instanciável — corresponde a essa estrutura, portanto é útil para ver como a verificação se comporta antes de conectá-la ao seu próprio objeto de documento:

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

Substitua signed_document pelo seu próprio objeto de documento assim que ele expuser uma lista signatures na mesma estrutura — qualquer objeto com esse atributo funciona.


Etapa 4: Executar a Verificação de Comprometimento

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() percorre cada assinatura em signed_document.signatures, procurando por conteúdo não assinado anexado após o intervalo de bytes assinado de cada assinatura. Um CompromiseCheckResult resume o resultado: compromised e has_compromised_signatures reportam o mesmo booleano sob dois nomes, signatures_coverage indica quantas assinaturas foram examinadas e reasons lista uma explicação legível para cada problema encontrado.


Etapa 5: Lidar com um Documento Sem Assinaturas

Uma lista signatures vazia ou ausente não é uma condição de erro — ela é relatada da mesma forma que um documento sem nada a ser verificado:

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

Passar SignaturesCompromiseDetector(None) — o padrão do construtor — tem o mesmo comportamento.

Problemas Comuns e Correções

compromised is False para um PDF que você sabe que foi editado após a assinatura

SignaturesCompromiseDetector procura especificamente por bytes não assinados acrescentados após o intervalo de bytes assinados de uma assinatura — um padrão típico de adulteração ingênua por atualização incremental. Não realiza a verificação completa de assinatura criptográfica. Para isso, chame validate() no objeto PdfSignature individual.

compromised and has_compromised_signatures parecem redundantes

Eles têm o mesmo valor: compromised é uma propriedade calculada que devolve has_compromised_signatures. Use o nome que ficar melhor no seu código.

Nenhuma exceção é lançada quando o documento não tem signatures atributo algum

SignaturesCompromiseDetector trata um documento sem o atributo signatures, ou document=None, da mesma forma que um documento não assinado — check() devolve um resultado com has_compromised_signatures=False e reasons=["unsigned document"] ao invés de gerar erro.

Um malformado PdfSignature não é sinalizado

check() ignora qualquer assinatura cujo byte_range não seja uma lista de 4 elementos, ou cujo reference_data não seja bytes/bytearray, ao invés de gerar erro ou relatá-la como comprometida. Uma assinatura construída com a forma errada é silenciosamente excluída da verificação, não sinalizada.

Confundindo este detector com a criação de assinatura

SignaturesCompromiseDetector e CompromiseCheckResult apenas inspecionam assinaturas que já existem em um documento — não possuem método para criar, aplicar ou incorporar uma nova assinatura.

Perguntas Frequentes

O que exatamente conta como “comprometido” aqui?

Bytes significativos, não-brancos, anexados ao PDF após a faixa de bytes assinada de uma assinatura — com duas exceções que o detector já considera: uma assinatura ou carimbo de tempo posterior que também cobre esses bytes, e uma atualização incremental que apenas adiciona material de validação (como um /DSS) sem sobrepor novo conteúdo como anotações.

Isso verifica a validade criptográfica da própria assinatura?

Não. SignaturesCompromiseDetector verifica padrões de adulteração ao redor do intervalo de bytes assinado. A validade criptográfica é uma verificação separada, disponível através de PdfSignature.validate().

O que signatures_coverage me informa?

O número de assinaturas que a verificação realmente examinou no documento fornecido — útil para confirmar que o detector viu as assinaturas que você esperava antes de confiar em um resultado limpo.

Posso verificar um documento com várias assinaturas de uma só vez?

Sim. check() itera cada entrada em signed_document.signatures e retorna um CompromiseCheckResult agregado que cobre todas elas.

Preciso criar objetos PdfSignature eu mesmo no uso normal?

Não — a construção de PdfSignature da Etapa 3 serve para explorar o comportamento do detector diretamente. Em um fluxo de trabalho real, passe qualquer objeto que seu código de carregamento de documento já produza, contanto que ele exponha uma lista signatures de entradas com formato PdfSignature.

Ver também

 Português