یک امضای دیجیتال ثبت می‌کند که چه کسی سند را امضا کرده است. یک مهر زمان معتبر چه زمانی را ثبت می‌کند و این زمان از یک مرجع زمان مستقل (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 را برمی‌گرداند که با گواهی خود امضا شده و هش را به زمان خاصی پیوند می‌دهد. این توکن داخل امضا ذخیره می‌شود. سپس یک تأییدکننده می‌تواند نشان دهد که امضا در همان لحظه وجود داشته است، که زمانی که گواهی امضا بعداً منقضی یا لغو شود، اهمیت دارد.

پیش‌نیازها

قبل از اجرای مثال، اطمینان حاصل کنید که موارد زیر را دارید:

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 گمشده، در لینوکسزمان‌اجرای .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 مراجعه کنید.

پرسش‌های متداول

  1. یک زمان‌ساز معتبر چه چیزی به امضای دیجیتال اضافه می‌کند؟
    یک مرجع زمان‌ساز (TSA) زمان ایجاد امضا را تأیید می‌کند. این زمان از یک طرف سوم مستقل به‌دست می‌آید نه از ساعت کامپیوتر امضاکننده، و به تأییدکننده امکان می‌دهد نشان دهد که امضا قبل از انقضای گواهی امضا یا لغو آن وجود داشته است.

  2. کدام نسخه از Aspose.Words از زمان‌ساز در DigitalSignatureUtil پشتیبانی می‌کند؟
    نسخه ۲۶.۹ Aspose.Words for Python via .NET ویژگی‌های SignOptions.timestamp_settings، XmlDsigLevel.X_AD_ES_T و کلاس DigitalSignatureTimestampSettings را اضافه کرد. نسخه‌های قبلی فقط می‌توانستند امضاها را در خروجی PDF زمان‌ساز کنند.

  3. آیا باید هر دو xml_dsig_level و timestamp_settings را تنظیم کنم؟
    بله. اگر فقط یکی از آن‌ها تنظیم شود، Aspose.Words همچنان سند را امضا می‌کند اما زمان‌ساز را درخواست یا درج نمی‌کند و خطایی نیز صادر نمی‌شود.

  4. کدام فرمت‌های فایل می‌توانند زمان‌ساز شوند؟
    فایل‌های DOCX و DOC که با X_AD_ES_T امضا شده‌اند، زمان‌ساز دریافت می‌کنند. امضای یک فایل ODT با زمان‌ساز باعث بروز خطایی می‌شود که می‌گوید این فرمت از زمان‌ساز پشتیبانی نمی‌کند.

  5. آیا is_valid تأیید می‌کند که زمان‌ساز معتبر است؟
    خیر. DigitalSignature.is_valid فقط امضا را بررسی می‌کند. برای تأیید زمان‌ساز، باید بررسی کنید که XML امضا شامل یک توکن زمان‌ساز باشد و آن توکن را با ابزاری مانند OpenSSL بررسی کنید.

  6. اگر TSA قابل دسترسی نباشد چه اتفاقی می‌افتد؟
    DigitalSignatureUtil.sign یک RuntimeError ایجاد می‌کند که مشکل شبکه، احراز هویت یا زمان‌سری را توصیف می‌کند. مسیر مقصد ممکن است به‌عنوان یک فایل خالی باقی بماند، بنابراین قبل از تلاش مجدد آن را حذف کنید.

دریافت یک لایسنس رایگان و پشتیبانی