デジタル署名は、誰が文書に署名したかを記録します。
信頼できるタイムスタンプは いつ を記録し、その時間は署名者のコンピュータの時計ではなく、独立したタイムスタンプ認証局 (TSA) から取得されます。
このチュートリアルでは、Python でタイムスタンプ付き XAdES‑T 署名を使用して Word 文書に署名する方法と、ファイル内にタイムスタンプが含まれていることを確認する方法を示します。
主なポイント
- 両方
SignOptions.xml_dsig_level = XmlDsigLevel.X_AD_ES_TとSignOptions.timestamp_settingsを設定してください。どちらか一方だけを設定すると、タイムスタンプなしの署名が生成され、エラーは通知されません。 - Aspose.Words は
DigitalSignatureUtil.signの実行中にタイムスタンプを要求するため、その呼び出しには TSA へのネットワークアクセスが必要です。 - DOCX と DOC ファイルはタイムスタンプを付与できます。ODT ファイルはできません。
DigitalSignature.is_validは署名をチェックし、タイムスタンプはチェックしません。タイムスタンプは別途確認してください。
信頼できるタイムスタンプが署名にもたらすもの
Aspose.Words が作成するすべての署名には、SignOptions.sign_time で設定される署名時刻が含まれます。その値は署名者のマシンから取得されるため、文書の時間に異議を唱える者はその時刻にも異議を唱えることができます。
XAdES‑T 署名は独立した証拠を追加します。ドキュメントが署名された後、Aspose.Words は署名値のハッシュを TSA に送信します。TSA は RFC 3161 トークンを返し、独自の証明書で署名され、ハッシュを特定の時刻に結び付けます。そのトークンは署名内に保存されます。検証者はその署名がその時点で存在したことを示すことができ、署名証明書が後で期限切れになるか取り消される場合に最も重要です。
前提条件
例を実行する前に、以下が揃っていることを確認してください:
- Aspose.Words for Python via .NET 26.9 or later. インストールまたはアップグレードするには PyPI から:
pip install --upgrade "aspose-words>=26.9"
- 署名証明書 を PKCS#12 形式(
.pfxまたは.p12)で、パスワードと共に。 - タイムスタンプ認証局 URL。例では FreeTSA (
https://freetsa.org/tsr) を使用しています。これはテストに便利な無料の公開 TSA です。本番用ドキュメントでは、組織または証明書プロバイダーが推奨する TSA を使用してください。ドキュメントを検証する人々がその TSA の証明書を信頼できる必要があります。 - TSA 資格情報、TSA が認証を必要とする場合のみ。
ライセンスがない場合、Aspose.Words は制限付きの評価モードで実行されます。テスト中にこれらの制限を解除するには、一時ライセンス を使用します。
信頼できるタイムスタンプでWordドキュメントに署名する
以下のスクリプトは、DOCXファイルにXAdES‑T署名を付与し、TSAからのタイムスタンプを埋め込みます。
import datetime
import aspose.words as aw
# Replace these values with your own files and credentials.
INPUT_DOC = "contract.docx"
OUTPUT_DOC = "contract-signed.docx"
CERT_FILE = "signing-cert.pfx"
CERT_PASSWORD = "your-pfx-password"
TSA_URL = "https://freetsa.org/tsr"
TSA_USER = "" # Fill in only if your TSA requires authentication.
TSA_PASSWORD = ""
# Load the signing certificate from a PKCS#12 file.
cert_holder = aw.digitalsignatures.CertificateHolder.create(
file_name=CERT_FILE, password=CERT_PASSWORD)
# Request an XAdES-T signature and point it at a timestamp authority.
sign_options = aw.digitalsignatures.SignOptions()
sign_options.xml_dsig_level = aw.digitalsignatures.XmlDsigLevel.X_AD_ES_T
sign_options.timestamp_settings = aw.digitalsignatures.DigitalSignatureTimestampSettings(
server_url=TSA_URL,
user_name=TSA_USER,
password=TSA_PASSWORD,
timeout=datetime.timedelta(seconds=60), # Default is 100 seconds.
)
# Sign the document. Aspose.Words contacts the TSA during this call.
aw.digitalsignatures.DigitalSignatureUtil.sign(
src_file_name=INPUT_DOC,
dst_file_name=OUTPUT_DOC,
cert_holder=cert_holder,
sign_options=sign_options,
)
print(f"Signed with a trusted timestamp: {OUTPUT_DOC}")
コードの仕組み
CertificateHolder.createは.pfxファイルから秘密鍵と証明書チェーンを読み取ります。パスワードが間違っている場合、署名が開始される前にここで失敗します。XmlDsigLevel.X_AD_ES_Tは Aspose.Words に XAdES-T 署名を作成するよう指示します。これは XAdES-EPES に署名タイムスタンプを加えたものです。DigitalSignatureTimestampSettingsは TSA の URL、オプションのユーザー名とパスワード、オプションのタイムアウトを保持します。匿名リクエストを受け付ける TSA では空文字列でも問題ありません。TSA が HTTP 認証チャレンジで応答した場合、Aspose.Words は提供された資格情報を送信します。DigitalSignatureUtil.signは署名済みのコピーをOUTPUT_DOCに書き込み、入力ファイルは変更しません。未署名のドキュメントに署名する場合、入力に既に署名があると、出力には既存の署名と新しい署名の両方が含まれます。
タイムスタンプが埋め込まれていることを確認する
Aspose.Words が返す DigitalSignature オブジェクトはタイムスタンプを公開せず、is_valid もそれをチェックしません。テストでは、タイムスタンプ トークンを意図的に破損させたドキュメントでも is_valid が True と報告されました。タイムスタンプを確認するには、DOCX パッケージに保存されている署名 XML を確認してください。
import base64
import re
import zipfile
import aspose.words as aw
SIGNED_DOC = "contract-signed.docx"
# 1. Check the signature itself.
for sig in aw.digitalsignatures.DigitalSignatureUtil.load_signatures(SIGNED_DOC):
print(f"Signer: {sig.subject_name} | valid: {sig.is_valid}")
# 2. Check that a timestamp token was embedded, and save it for inspection.
with zipfile.ZipFile(SIGNED_DOC) as package:
for part in package.namelist():
if part.startswith("_xmlsignatures/sig") and part.endswith(".xml"):
xml = package.read(part).decode("utf-8")
match = re.search(r"<(?:\w+:)?EncapsulatedTimeStamp[^>]*>([^<]+)<", xml)
if match:
with open("timestamp-token.der", "wb") as f:
f.write(base64.b64decode(match.group(1)))
print(f"{part}: timestamp embedded (saved to timestamp-token.der)")
else:
print(f"{part}: no timestamp found")
署名された DOCX の場合、次のような出力が表示されます:
Signer: CN=Your Name | valid: True
_xmlsignatures/sig1.xml: timestamp embedded (saved to timestamp-token.der)
TSAが認証した時間を読み取るには、保存されたトークンをOpenSSLに渡します:
openssl ts -reply -token_in -in timestamp-token.der -token_out -text
Time stamp 行は GMT の認証された時間を示し、TSA 行はそれを発行した権限を特定します。
このチェックは DOCX パッケージ形式を読み取ります。DOC ファイルは署名をバイナリ コンテナに保存するため、ZIP ベースのスクリプトは適用できません。
署名およびタイムスタンプエラーのトラブルシューティング
| 症状 | 考えられる原因 | 対策 |
|---|---|---|
| 署名は成功するが、タイムスタンプが埋め込まれない | xml_dsig_level = X_AD_ES_T と timestamp_settings のうち片方だけが設定されていた | sign を呼び出す前に両方を設定する。XML_D_SIG または X_AD_ES_EPES を使用すると、タイムスタンプ設定は無視される。 |
RuntimeError に (401) Unauthorized が含まれる | TSA が認証情報を必要としている、または認証情報が間違っている | TSA プロバイダーから発行されたユーザー名とパスワードを渡す。 |
RuntimeError に接続拒否またはプロキシエラーが含まれる | TSA の URL が間違っている、またはファイアウォールやプロキシがリクエストをブロックしている | URL を確認し、スクリプトを実行しているマシンが TSA に到達できることを確認する。 |
RuntimeError に The operation has timed out が含まれる | TSA がタイムアウト内に応答しなかった | 再試行するか、DigitalSignatureTimestampSettings により長い timeout を渡す。 |
| エラー後に空の出力ファイルが残る | sign が TSA リクエストが失敗する前に宛先ファイルを作成する | 再試行前に宛先ファイルを削除するか、テンポラリパスに書き込み、成功した呼び出し後にリネームする。 |
RuntimeError がこのファイル形式ではタイムスタンプがサポートされていないと言う | 入力が ODT ファイルである | DOCX または DOC ファイルにタイムスタンプを付けるか、PDF に変換して以下で説明する PDF 署名ルートを使用する。 |
No usable version of libssl was found、または Linux で ICU パッケージが見つからないというクラッシュ | Python パッケージに同梱された .NET ランタイムは OpenSSL 1.1 とサポートされている ICU バージョンが必要 | OpenSSL 1.1 をインストールするか、サポートされている ICU をインストールする。アプリケーションがロケール固有のフォーマットを必要としない場合は、ICU エラー対策として DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 を設定する。 |
代替案: PDF 出力で署名にタイムスタンプを付ける
受信者が署名済み Word ファイルではなく PDF を必要とする場合、DigitalSignatureUtil は必要ありません。PdfSaveOptions.digital_signature_details.timestamp_settings に PdfDigitalSignatureTimestampSettings オブジェクトを設定して、保存時に PDF に署名とタイムスタンプを付けます。この方法は 26.9 よりはるかに前から利用可能です。PdfDigitalSignatureTimestampSettings リファレンス には完全なサンプルが含まれています。
次のステップ
署名行を追加したり、署名行画像で署名したり、既存の署名を削除したりするには、Aspose.Words for Python のドキュメントにある デジタル署名の操作 を参照してください。
FAQs
信頼できるタイムスタンプはデジタル署名に何を追加しますか?
タイムスタンプ機関 (TSA) は署名が作成された時刻を認証します。その時刻は署名者のコンピュータの時計ではなく、独立した第三者から取得され、検証者は署名が署名証明書の有効期限切れや失効前に存在していたことを示すことができます。どの Aspose.Words バージョンが DigitalSignatureUtil のタイムスタンプをサポートしていますか?
Aspose.Words for Python via .NET のバージョン 26.9 でSignOptions.timestamp_settings、XmlDsigLevel.X_AD_ES_T、およびDigitalSignatureTimestampSettingsクラスが追加されました。以前のバージョンでは PDF 出力の署名にのみタイムスタンプを付与できます。xml_dsig_level と timestamp_settings の両方を設定する必要がありますか?
はい。どちらか一方だけを設定した場合、Aspose.Words はドキュメントに署名はしますが、タイムスタンプの要求や埋め込みは行わず、エラーも発生しません。どのファイル形式にタイムスタンプを付与できますか?
X_AD_ES_Tで署名された DOCX および DOC ファイルにはタイムスタンプが付与されます。ODT ファイルにタイムスタンプを付与しようとすると、該当フォーマットがタイムスタンプに対応していない旨のエラーが発生します。is_valid はタイムスタンプが有効であることを確認しますか?
いいえ。DigitalSignature.is_validは署名自体をチェックします。タイムスタンプを確認するには、署名 XML にタイムスタンプトークンが含まれているかを確認し、OpenSSL などのツールでそのトークンを検査してください。TSA に到達できない場合はどうなりますか?
DigitalSignatureUtil.signはネットワーク、認証、またはタイムアウトの問題を示すRuntimeErrorをスローします。宛先パスには空のファイルが残る可能性があるため、再試行する前に削除してください。
