Python で PDF セキュリティ署名を追加する方法
Aspose.PDF の Python 用 FOSS には、既に署名された 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 findingscheck() は signed_document.signatures 内のすべての署名を走査し、各署名の署名済みバイト範囲の後に付加された未署名コンテンツがないか調べます。CompromiseCheckResult は結果を要約します: compromised と has_compromised_signatures は同じ真偽値を2つの名前で報告し、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 でない署名を、例外を発生させたり「compromised」と報告したりする代わりにスキップします。形状が間違っている署名はチェックから黙って除外され、フラグは付けられません。
この検出器と署名作成を混同すること
SignaturesCompromiseDetector と CompromiseCheckResult は、ドキュメントにすでに存在する署名のみを検査します — 新しい署名を作成、適用、または埋め込む手段はありません。
よくある質問
ここで「compromised」と見なされる条件は正確には何ですか?
署名のサインバイト範囲の後に PDF に付加された意味のある非空白バイト — ただし、検出器がすでに考慮している 2 つの例外があります: それらのバイトを自らカバーする後続の署名またはタイムスタンプ、そして注釈などの新しいコンテンツを重ねず、検証材料(例: /DSS)のみを追加するインクリメンタル更新。
これで署名自体の暗号的有効性が検証されますか?
いいえ。SignaturesCompromiseDetector は署名されたバイト範囲周辺の改ざんパターンをチェックします。暗号的有効性は別のチェックで、PdfSignature.validate() を通じて利用できます。
signatures_coverage は何を教えてくれますか?
チェックが実際に検査した、渡されたドキュメント内の署名の数です — クリーンな結果を信頼する前に、検出器が期待した署名を確認できたかどうかを判断するのに役立ちます。
複数の署名があるドキュメントを一度にチェックできますか?
はい。check() は signed_document.signatures のすべてのエントリを反復し、すべてをカバーする単一の集約 CompromiseCheckResult を返します。
通常の使用時に自分で PdfSignature オブジェクトを構築する必要がありますか?
いいえ — ステップ3の PdfSignature 構築は、検出器の動作を直接調査するためのものです。実際のワークフローでは、ドキュメント読み込みコードがすでに生成するオブジェクトをそのまま渡せばよく、signatures の PdfSignature 形状のエントリのリストを公開している限り問題ありません。