ลายเซ็นดิจิทัลบันทึกว่าผู้ใดได้ลงนามในเอกสาร ส่วนการทำเครื่องหมายเวลาที่เชื่อถือได้บันทึก เมื่อไหร่ และเวลานั้นมาจากหน่วยงานให้เวลาที่เป็นอิสระ (TSA) แทนที่จะเป็นนาฬิกาบนคอมพิวเตอร์ของผู้ลงนาม บทแนะนำนี้จะแสดงวิธีการลงนามเอกสาร Word ด้วยลายเซ็น XAdES‑T ที่มีการทำเครื่องหมายเวลาใน Python แล้วตรวจสอบว่าการทำเครื่องหมายเวลาได้ถูกบันทึกไว้ในไฟล์

ประเด็นสำคัญ

  • ตั้งค่า **ทั้งสอง ** SignOptions.xml_dsig_level = XmlDsigLevel.X_AD_ES_T และ SignOptions.timestamp_settings. การตั้งค่าเพียงอย่างเดียวจะทำให้ลายเซ็นไม่มี timestamp และไม่มีข้อผิดพลาดบอกคุณเช่นนั้น
  • Aspose.Words ขอ timestamp ระหว่าง DigitalSignatureUtil.sign ดังนั้นการเรียกนี้ต้องการการเข้าถึงเครือข่ายไปยัง TSA
  • ไฟล์ DOCX และ DOC สามารถใส่ timestamp ได้ ไฟล์ ODT ไม่สามารถทำได้
  • DigitalSignature.is_valid ตรวจสอบลายเซ็น ไม่ใช่ timestamp ยืนยัน timestamp แยกต่างหาก

สิ่งที่การทำเครื่องหมายเวลาเชื่อถือได้เพิ่มให้กับลายเซ็น

ลายเซ็นทุกฉบับที่สร้างโดย Aspose.Words จะมีเวลาลายเซ็นซึ่งกำหนดโดย SignOptions.sign_time. ค่าดังกล่าวมาจากเครื่องของผู้ลงลายเซ็น ดังนั้นผู้ที่โต้แยกเอกสารก็สามารถโต้แยกเวลาได้เช่นกัน.

ลายเซ็น XAdES‑T เพิ่มหลักฐานอิสระ หลังจากเอกสารถูกลงนามแล้ว, Aspose.Words จะส่งแฮชของค่าลายเซ็นไปยัง TSA. TSA จะคืนโทเคน RFC 3161 ที่ลงนามด้วยใบรับรองของตนเอง ซึ่งผูกแฮชกับเวลาที่กำหนด โทเคนนั้นจะถูกเก็บไว้ภายในลายเซ็น ผู้ตรวจสอบจึงสามารถแสดงได้ว่าลายเซ็นมีอยู่ในขณะนั้น ซึ่งสำคัญที่สุดเมื่อใบรับรองการลงนามในภายหลังหมดอายุหรือถูกเพิกถอน.

ข้อกำหนดเบื้องต้น

ก่อนที่คุณจะรันตัวอย่างนี้, ตรวจสอบให้แน่ใจว่าคุณมี:

pip install --upgrade "aspose-words>=26.9"
  • ใบรับรองการลงนาม in PKCS#12 format (.pfx หรือ .p12) and its password.
  • URL ของหน่วยงานให้บริการ timestamp. ตัวอย่างใช้ FreeTSA (https://freetsa.org/tsr), ซึ่งเป็น TSA สาธารณะฟรีที่สะดวกสำหรับการทดสอบ. สำหรับเอกสารในสภาพแวดล้อมการผลิต, ใช้ TSA ที่องค์กรของคุณหรือผู้ให้บริการใบรับรองแนะนำ, เนื่องจากผู้ตรวจสอบเอกสารของคุณต้องเชื่อถือใบรับรองของ TSA นั้น.
  • ข้อมูลประจำตัวของ TSA, เฉพาะเมื่อ TSA ของคุณต้องการการยืนยันตัวตน.

หากไม่มีใบอนุญาต Aspose.Words จะทำงานในโหมดประเมินพร้อมข้อจำกัด. ใบอนุญาตชั่วคราว จะลบข้อจำกัดเหล่านั้นขณะคุณทำการทดสอบ.

ลงนามเอกสาร Word ด้วย Timestamp ที่เชื่อถือได้

สคริปต์ต่อไปนี้ทำการลงนามไฟล์ DOCX ด้วยลายเซ็น XAdES‑T และฝัง timestamp จาก 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 พร้อมกับ timestamp ของลายเซ็น
  • DigitalSignatureTimestampSettings เก็บ URL ของ TSA, ชื่อผู้ใช้และรหัสผ่านที่เป็นตัวเลือก, และ timeout ที่เป็นตัวเลือก ค่าสตริงว่างก็ใช้ได้สำหรับ TSA ที่ยอมรับคำขอแบบไม่ระบุตัวตน หาก TSA ตอบกลับด้วยการท้าทายการตรวจสอบสิทธิ์ HTTP, Aspose.Words จะส่งข้อมูลประจำตัวที่คุณให้มา
  • DigitalSignatureUtil.sign เขียนสำเนาที่เซ็นแล้วไปยัง OUTPUT_DOC และไม่เปลี่ยนแปลงไฟล์อินพุต ทำการเซ็นเอกสารที่ยังไม่ได้เซ็น: หากอินพุตมีลายเซ็นอยู่แล้ว, เอาต์พุตจะมีทั้งลายเซ็นเดิมและลายเซ็นใหม่.

ตรวจสอบว่ามีการฝัง Timestamp หรือไม่

อ็อบเจ็กต์ DigitalSignature ที่ Aspose.Words คืนค่ามาไม่ได้เปิดเผย timestamp, และ is_valid ไม่ได้ตรวจสอบมัน ในการทดสอบ, เอกสารที่โทเคน timestamp ถูกทำให้เสียโดยเจตนายังรายงาน is_valid เป็น True เพื่อยืนยัน timestamp ให้ดูภายใน 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 จะไม่สามารถใช้ได้กับไฟล์นี้.

แก้ไขปัญหาการลงนามและข้อผิดพลาดของการทำเครื่องหมายเวลา

SymptomLikely causeWhat to do
การลงนามสำเร็จ แต่ไม่มีการฝังเครื่องหมายเวลามีการตั้งค่าเพียงหนึ่งอย่างระหว่าง xml_dsig_level = X_AD_ES_T และ timestamp_settings เท่านั้นตั้งค่าทั้งสองก่อนเรียก sign. หากใช้ XML_D_SIG หรือ X_AD_ES_EPES การตั้งค่าเครื่องหมายเวลาจะถูกละเลย
RuntimeError ที่ระบุ (401) UnauthorizedTSA ต้องการข้อมูลประจำตัว หรือข้อมูลประจำตัวไม่ถูกต้องส่งชื่อผู้ใช้และรหัสผ่านที่ออกโดยผู้ให้บริการ TSA ของคุณ
RuntimeError ที่ระบุการเชื่อมต่อถูกปฏิเสธหรือข้อผิดพลาดของพร็อกซีURL ของ TSA ไม่ถูกต้อง หรือไฟร์วอลล์หรือพร็อกซีบล็อกคำขอตรวจสอบ URL และยืนยันว่าเครื่องที่รันสคริปต์ของคุณสามารถเข้าถึง TSA ได้
RuntimeError ที่ระบุ The operation has timed outTSA ไม่ตอบภายในเวลาที่กำหนดลองใหม่อีกครั้ง หรือส่งค่า timeout ที่ยาวกว่าไปยัง DigitalSignatureTimestampSettings
ไฟล์ผลลัพธ์ว่างเปล่ายังคงอยู่หลังจากเกิดข้อผิดพลาดsign สร้างไฟล์ปลายทางก่อนที่คำขอ TSA จะล้มเหลวลบไฟล์ปลายทางก่อนลองใหม่อีกครั้ง หรือเขียนไปยังเส้นทางชั่วคราวและเปลี่ยนชื่อหลังจากการเรียกสำเร็จ
RuntimeError บอกว่าการทำเครื่องหมายเวลาไม่รองรับโดยรูปแบบไฟล์นี้ไฟล์อินพุตเป็นไฟล์ ODTทำเครื่องหมายเวลาไฟล์ DOCX หรือ DOC, หรือแปลงเป็น PDF แล้วใช้เส้นทางการลงนาม PDF ที่อธิบายด้านล่าง
No usable version of libssl was found, หรือการพังเกี่ยวกับแพ็กเกจ ICU ที่หายไป, บน Linuxรันไทม์ .NET ที่รวมมาพร้อมกับแพ็กเกจ Python ต้องการ 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.

FAQs

  1. การเพิ่ม timestamp ที่เชื่อถือได้ให้กับลายเซ็นดิจิทัลมีผลอย่างไร?
    หน่วยงานให้บริการ timestamp (TSA) จะรับรองเวลาที่ลายเซ็นถูกสร้างขึ้น เวลาเหล่านี้มาจากบุคคลที่สามที่เป็นอิสระ ไม่ใช่นาฬิกาคอมพิวเตอร์ของผู้ลงนาม และทำให้ผู้ตรวจสอบสามารถแสดงว่าลายเซ็นมีอยู่ก่อนที่ใบรับรองการลงนามจะหมดอายุหรือถูกเพิกถอน

  2. เวอร์ชันของ Aspose.Words ใดที่รองรับการทำ timestamp ใน DigitalSignatureUtil?
    เวอร์ชัน 26.9 ของ Aspose.Words for Python via .NET ได้เพิ่ม SignOptions.timestamp_settings, XmlDsigLevel.X_AD_ES_T และคลาส DigitalSignatureTimestampSettings เวอร์ชันก่อนหน้านี้สามารถทำ timestamp ให้กับลายเซ็นได้เฉพาะในผลลัพธ์ PDF เท่านั้น

  3. ฉันต้องตั้งค่า xml_dsig_level และ timestamp_settings ทั้งสองหรือไม่?
    ใช่ หากตั้งค่าเพียงหนึ่งอย่าง Aspose.Words จะยังคงลงนามเอกสาร แต่จะไม่ร้องขอหรือฝัง timestamp และจะไม่เกิดข้อผิดพลาด

  4. รูปแบบไฟล์ใดบ้างที่สามารถทำ timestamp ได้?
    ไฟล์ DOCX และ DOC ที่ลงนามด้วย X_AD_ES_T จะได้รับ timestamp การลงนามไฟล์ ODT ด้วย timestamp จะทำให้เกิดข้อผิดพลาดระบุว่ารูปแบบนี้ไม่รองรับการทำ timestamp

  5. is_valid ยืนยันว่า timestamp นั้นถูกต้องหรือไม่?
    ไม่ DigitalSignature.is_valid ตรวจสอบเพียงลายเซ็นเอง เพื่อยืนยัน timestamp ให้ตรวจสอบว่า XML ของลายเซ็นมี token ของ timestamp อยู่หรือไม่ และตรวจสอบ token นั้นด้วยเครื่องมือเช่น OpenSSL

  6. จะเกิดอะไรขึ้นหากไม่สามารถเชื่อมต่อกับ TSA ได้?
    DigitalSignatureUtil.sign จะโยน RuntimeError ที่อธิบายปัญหาเครือข่าย การยืนยันตัวตน หรือการหมดเวลา เส้นทางปลายทางอาจเหลือเป็นไฟล์เปล่า ดังนั้นให้ลบไฟล์นั้นก่อนลองใหม่

รับใบอนุญาตและการสนับสนุนฟรี