Цифровий підпис фіксує, хто підписав документ. Довірчий мітка часу фіксує коли, і цей час надходить від незалежного органу часових міток (TSA), а не від годинника на комп’ютері підписувача. У цьому підручнику показано, як підписати документ Word підписом XAdES‑T з міткою часу в Python, а потім підтвердити, що мітка часу міститься у файлі.
Ключові висновки
- Встановіть обидва
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містить URL TSA, необов’язкове ім’я користувача та пароль, а також необов’язковий тайм-аут. Порожні рядки підходять для TSA, який приймає анонімні запити. Якщо TSA відповідає HTTP‑викликом автентифікації, Aspose.Words надсилає надані вами облікові дані.DigitalSignatureUtil.signзаписує підписану копію уOUTPUT_DOCі залишає вхідний файл без змін. Підписати непідписаний документ: якщо вхідний файл вже має підпис, вихідний міститиме як існуючий підпис, так і новий.
Перевірте, чи був вбудований мітка часу
Об’єкти DigitalSignature, які повертає Aspose.Words, не розкривають мітку часу, і is_valid її не перевіряє. При тестуванні документ, у якого токен мітки часу був навмисно пошкоджений, все одно повідомляв is_valid як True. Щоб підтвердити мітку часу, подивіться всередину XML підпису, що зберігається у пакеті DOCX:
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, що містить відмову з’єднання або помилку проксі | URL TSA неправильний, або брандмауер чи проксі блокує запит | Перевірте URL і переконайтеся, що машина, на якій виконується скрипт, може досягти TSA. |
RuntimeError, що містить The operation has timed out | TSA не відповіла протягом встановленого часу | Повторіть спробу або передайте довший timeout у DigitalSignatureTimestampSettings. |
| Після помилки залишається порожній вихідний файл | sign створює файл призначення до того, як запит до TSA зазнає збою | Видаліть файл призначення перед повторною спробою або запишіть у тимчасовий шлях і перейменуйте його після успішного виклику. |
RuntimeError, який повідомляє, що мітка часу не підтримується цим форматом файлу | Вхідний файл у форматі ODT | Додавайте мітку часу до файлів DOCX або DOC, або конвертуйте у PDF і використайте шлях підпису PDF, описаний нижче. |
No usable version of libssl was found, або збій через відсутній пакет ICU, у Linux | Вбудований у Python пакет .NET runtime потребує OpenSSL 1.1 та підтримуваної версії ICU | Встановіть OpenSSL 1.1 або підтримувану версію ICU. Якщо вашому застосунку не потрібне форматування, специфічне для культури, встановіть DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 для усунення помилки ICU. |
Альтернатива: Додавання мітки часу до підпису у PDF
Якщо вашим одержувачам потрібен PDF, а не підписаний файл Word, вам не потрібен DigitalSignatureUtil. Підпишіть і додайте мітку часу до PDF під час збереження, встановивши PdfSaveOptions.digital_signature_details.timestamp_settings у об’єкт PdfDigitalSignatureTimestampSettings. Цей спосіб доступний набагато довше, ніж 26.9. У PdfDigitalSignatureTimestampSettings reference міститься повний приклад.
Наступні кроки
Щоб додати рядки підпису, підписати за допомогою зображення рядка підпису або видалити існуючі підписи, перегляньте Робота з цифровими підписами у документації Aspose.Words for Python.
Питання та відповіді
Що додає довірчий часовий штамп до цифрового підпису?
Установа часових штампів (TSA) підтверджує час створення підпису. Цей час надходить від незалежної третьої сторони, а не від системного годинника підписанта, і дозволяє верифікатору показати, що підпис існував до того, як підписний сертифікат закінчив термін дії або був відкликаний.Яка версія Aspose.Words підтримує встановлення часових штампів у DigitalSignatureUtil?
Версія 26.9 Aspose.Words for Python via .NET додалаSignOptions.timestamp_settings,XmlDsigLevel.X_AD_ES_Tта класDigitalSignatureTimestampSettings. Попередні версії можуть встановлювати часові штампи лише для підписів у PDF‑виводі.Чи потрібно встановлювати і
xml_dsig_level, іtimestamp_settings?
Так. Якщо встановлено лише один з цих параметрів, Aspose.Words все одно підписує документ, але не запитує і не вбудовує часовий штамп, і помилки не генерує.Які формати файлів можна підписати з часовим штампом?
Файли DOCX і DOC, підписані зX_AD_ES_T, отримують часовий штамп. Підписання файлу ODT з часовим штампом викликає помилку, що даний формат не підтримує часові штампи.Чи підтверджує
is_validдійсність часового штампу?
Ні.DigitalSignature.is_validперевіряє лише сам підпис. Щоб підтвердити часовий штамп, перевірте, чи XML підпису містить токен часового штампу, і проаналізуйте його за допомогою інструменту, наприклад OpenSSL.Що трапляється, якщо TSA недоступна?
DigitalSignatureUtil.signгенеруєRuntimeError, який описує проблему мережі, автентифікації або тайм‑ауту. Шлях призначення може залишитися порожнім файлом, тому його слід видалити перед повторною спробою.
