เพื่อให้ไฟล์ PDF ที่ลงลายเซ็นยังคงสามารถตรวจสอบความถูกต้องได้ในอีกหลายปีข้างหน้า หลังจากใบรับรองลายเซ็นหมดอายุและหน่วยงาน CA มีการสลับสับเปลี่ยนคีย์ PDFium Component สามารถสร้างลายเซ็น PAdES ระยะยาวบนระบบปฏิบัติการ Windows ได้: ซึ่งประกอบด้วยการระบุเวลาตามมาตรฐาน RFC 3161 สำหรับเวลาที่เชื่อถือได้, คลังความปลอดภัยของเอกสาร (Document Security Store - DSS) ที่ฝังข้อมูลยืนยันความถูกต้อง และการระบุเวลาเอกสารจดหมายเหตุ (DocTimeStamp) ครอบคลุมไฟล์ทั้งหมด การเพิ่มองค์ประกอบทั้งสามนี้สอดคล้องตามมาตรฐานระดับ PAdES B-T, B-LT และ B-LTA และ PDFium Component สามารถเข้าถึงระดับเหล่านี้ทั้งหมดได้จากการเรียกใช้คำสั่งเซ็นชื่อเพียงครั้งเดียว ความสามารถนี้รองรับเฉพาะบนระบบปฏิบัติการ Windows เท่านั้น โดยต้องผ่านการตรวจสอบด้วยคุณสมบัติ PadesCryptoAvailable
บทความนี้เป็นบทความตอนที่สามในซีรีส์ ตอนที่หนึ่งเรื่อง signing PDFs with PAdES B-B using PDFium VCL ได้นำเสนอรายละเอียดลายเซ็นพื้นฐาน ส่วนตอนที่สองเรื่อง inspecting PDF digital signatures and PAdES levels นำเสนอการอ่านข้อมูลลายเซ็นกลับและการวิเคราะห์ระดับมาตรฐานของลายเซ็น และในตอนนี้เราจะมาอธิบายเรื่องจดหมายเหตุเอกสาร: ซึ่งเป็นลายเซ็นที่จะต้องทนทานต่อการหมดอายุของใบรับรองและยังคงตรวจสอบความถูกต้องได้ยาวนานเป็นปีๆ ไม่ใช่หลักสัปดาห์
เหตุใดลายเซ็น PDF ที่ถูกต้องจึงไม่สามารถตรวจสอบความถูกต้องได้เมื่อเวลาผ่านไป?
ลายเซ็นพื้นฐานจะตอบคำถามเพียงข้อเดียว: คือมีไบต์ข้อมูลใดถูกแก้ไขหลังจากขั้นตอนการเซ็นชื่อหรือไม่ ลายเซ็นนี้ไม่สามารถพิสูจน์ได้ด้วยตัวเองว่าการเซ็นเกิดขึ้นเมื่อใด และข้อจำกัดนี้จะทำให้เกิดปัญหาในภายหลัง โครงสร้าง CMS มีการบันทึกแอตทริบิวต์เวลาเซ็นชื่อ แต่ผู้เซ็นเขียนข้อมูลนี้จากนาฬิกาของเครื่องตัวเอง ทำให้ตัวตรวจสอบไม่มีเหตุผลที่จะเชื่อถือข้อมูล เมื่อใบรับรองลายเซ็นหมดอายุหรือหน่วยงาน CA ทำการยกเลิกใบรับรองในภายหลัง ตัวตรวจสอบที่เข้มงวดจะไม่สามารถแยกแยะระหว่างลายเซ็นที่เซ็นในระหว่างที่ใบรับรองมีอายุการใช้งานกับการปลอมแปลงขึ้นมาหลังจากใบรับรองหมดอายุได้ ลายเซ็นนั้นปกติดีในวันที่ทำรายการ แต่กลับไม่สามารถตรวจสอบความถูกต้องได้ในเวลาต่อมาโดยไม่ใช่ความผิดของมันเอง
การจัดเก็บเอกสารระยะยาวจะเข้ามาแก้ไขปัญหานี้ผ่านสองขั้นตอน ขั้นแรกคือ ให้หน่วยงานรับรองเวลาภายนอก (Time Stamping Authority - TSA) ที่เชื่อถือได้ ทำการรับรองเวลาด้วยหลักคริปโตกราฟี เพื่อไม่ให้ต้องพึ่งพาความถูกต้องจากเครื่องคอมพิวเตอร์ของผู้เซ็น ขั้นที่สองคือ ฝังใบรับรองทุกใบ, ผลลัพธ์การยกเลิก และตัว CRL ที่จำเป็นสำหรับสร้างและตรวจสอบห่วงโซ่ความเชื่อถือไว้ภายในตัวไฟล์ PDF เอง เพื่อให้การยืนยันไม่ต้องพึ่งพาเซิร์ฟเวอร์ภายนอกที่อาจปิดตัวไปแล้วในเวลาที่ตรวจสอบ มาตรฐาน PAdES ซึ่งได้รับการรับรองเป็น ETSI EN 319 142-1 ได้แบ่งระดับข้อกำหนดเหล่านี้ และ PDFium Component จะเขียนโครงสร้างข้อมูลตามที่แต่ละระดับมาตรฐานกำหนด
ลายเซ็น PDF แบบ LTV หรือแบบระบุเวลาจดหมายเหตุคืออะไร?
มาตรฐาน PAdES กำหนดระดับพื้นฐานสี่ระดับที่ต่อยอดจากกันและกัน และ PDFium Component จะแสดงผลผ่าน enum TPadesLevel ได้แก่ (plB_B, plB_T, plB_LT, plB_LTA) ระดับ B-B คือลายเซ็นปกติ ระดับ B-T จะเพิ่มการระบุเวลาที่เชื่อถือได้ทับค่าลายเซ็น ระดับ B-LT (Long-Term) จะเพิ่มข้อมูลยืนยันความถูกต้องในไฟล์ ซึ่งเป็นคุณสมบัติที่คนทั่วไปเรียกว่า "LTV" ส่วนระดับ B-LTA (Long-Term with Archive timestamp) จะหุ้มข้อมูลทั้งหมดด้วยการระบุเวลาครอบคลุมไฟล์ทั้งหมดอีกชั้นหนึ่ง เพื่อให้ข้อมูลยืนยันความถูกต้องที่ฝังอยู่ได้รับการรับรองว่าไม่ถูกแก้ไขตั้งแต่กระบวนการจัดเก็บจดหมายเหตุ
การทำความเข้าใจในทางปฏิบัติเปรียบเสมือนขั้นบันได ระดับ B-T พิสูจน์ว่าเมื่อใด ระดับ B-LT พิสูจน์ว่าด้วยข้อมูลอะไรที่ลายเซ็นยังคงสามารถตรวจสอบความถูกต้องได้ ระดับ B-LTA พิสูจน์ว่าข้อมูลทั้งหมดไม่ถูกแก้ไขหลังจากถูกปิดผนึก และนี่คือระดับที่คุณสามารถต่ออายุได้ด้วยการเพิ่มระบุเวลาเอกสาร DocTimeStamp ใหม่ก่อนที่ตัวเก่าจะหมดอายุ เพื่อขยายอายุเอกสารจดหมายเหตุได้ไม่จำกัด สำหรับเอกสารสัญญาหรือเอกสารข้อกำหนดที่ต้องการการจัดเก็บระยะยาว ระดับ B-LTA คือเป้าหมาย และระดับ B-LT คือเกณฑ์ขั้นต่ำในทางปฏิบัติ
การเพิ่มเวลาที่เชื่อถือได้: PAdES B-T ด้วย RFC 3161
PDFium Component จะแปลงลายเซ็นระดับ B-B เป็น B-T โดยการกำหนดฟิลด์สองฟิลด์ในโครงสร้าง TPadesSignOptions: ปรับ Level เป็น plB_T และระบุที่อยู่ TsaUrl เมื่อระบุทั้งสองจุด ขั้นตอนการเซ็นชื่อจะนำข้อมูลไบต์ลายเซ็นดิบมาคำนวณแฮชด้วย SHA-256 แพ็กเกจแฮชนั้นเป็น messageImprint ตามมาตรฐาน RFC 3161 แล้วส่งคำร้องขอแบบ POST ไปยังหน่วยงานรับรองเวลา (TSA) ผ่าน WinHttp และนำโทเค็นที่ส่งกลับมาฝังเป็นแอตทริบิวต์ signature-time-stamp (รหัส OID 1.2.840.113549.1.9.16.2.14) ในโครงสร้าง SignerInfo unsignedAttrs [1] ตามข้อกำหนด EN 319 142-1 §6.3 การระบุเวลานี้จะครอบคลุมตัวค่าลายเซ็นโดยเจาะจง ซึ่งเป็นการผูกโยงเวลาที่เชื่อถือได้เข้ากับลายเซ็นนั้นๆ อย่างถูกต้อง
uses
PDFium, FPdfPades;
procedure SignWithTimestamp;
var
Pdf: TPdf;
Options: TPadesSignOptions;
begin
Pdf := TPdf.Create(nil);
try
if not Pdf.PadesCryptoAvailable then
raise Exception.Create('PAdES signing backend is Windows-only');
Pdf.FileName := 'contract.pdf';
Pdf.Active := True;
Options := TPadesSignOptions.Default;
Options.CertificateThumbprint := 'A1B2C3D4E5F6071829304152637485960A1B2C3D';
Options.Level := plB_T;
Options.TsaUrl := 'http://timestamp.example-tsa.com/tsr';
Options.Reason := 'Contract execution';
// Nonce left at 0: the component derives a unique anti-replay value.
Pdf.SignPades('contract-bt.pdf', Options);
finally
Pdf.Free;
end;
end;
ค่า CertificateThumbprint คือแฮช SHA-1 ในระบบฐานสิบหกของใบรับรองในคลังข้อมูลส่วนบุคคลของระบบ Windows (Current User "MY") ที่มีกุญแจส่วนตัวที่คุณสามารถนำมาใช้งานได้ ฟิลด์ Nonce คือค่าป้องกันการส่งข้อมูลซ้ำ (anti-replay) ตามมาตรฐาน RFC 3161 หากปล่อยค่าเป็นศูนย์ ตัวส่วนประกอบจะสร้างค่าที่ไม่ซ้ำกันในแต่ละการเรียกใช้ผ่านการคำนวณแฮช SHA-256 ร่วมกับตัวนับเวลา, เวลาจริง, จำนวนติ๊กนาฬิกา และไอดีของโปรเซส เพื่อป้องกันไม่ให้คำร้องขอสองตัวที่รันในมิลลิวินาทีเดียวกันเกิดความซ้ำกัน คุณควรระบุค่าด้วยตัวเองเฉพาะเมื่อคุณมีเอนจินสุ่มตัวเลขทางคริปโตกราฟีที่มั่นใจกว่าเท่านั้น ข้อควรระวังอย่างตรงไปตรงมาคือ: ระดับ B-T จำเป็นต้องเชื่อมต่อกับ TSA ได้สำเร็จ ดังนั้นการเซ็นชื่อจึงเป็นขั้นตอนที่มีการเชื่อมต่อเครือข่ายและขึ้นอยู่กับความพร้อมและเวลาตอบสนองของเซิร์ฟเวอร์ TSA
การฝังข้อมูลยืนยันความถูกต้อง: B-LT และ B-LTA ในขั้นตอนเดียว
การก้าวไปสู่การตรวจสอบระยะยาวคือการแก้ไขเพียงจุดเดียว: กำหนด Level เป็น plB_LTA และระบุ TsaUrl จากนั้น PDFium Component จะดำเนินการตามขั้นตอนทั้งหมดให้เสร็จสิ้นภายในคำสั่ง SignPades เดียว โดยเริ่มเซ็นชื่อแบบ B-B, ระบุเวลาแบบ B-T, แทรกคลัง DSS สำหรับ B-LT และเขียนการระบุเวลาเอกสารสำหรับ B-LTA โดยแต่ละส่วนจะเป็นการบันทึกแบบเพิ่มพูนทำให้ไบต์ข้อมูลก่อนหน้าไม่เสียหาย
procedure SignForArchive;
var
Pdf: TPdf;
Options: TPadesSignOptions;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'contract.pdf';
Pdf.Active := True;
Options := TPadesSignOptions.Default;
Options.CertificateThumbprint := 'A1B2C3D4E5F6071829304152637485960A1B2C3D';
Options.Level := plB_LTA; // drives B-B -> B-T -> B-LT -> B-LTA
Options.TsaUrl := 'http://timestamp.example-tsa.com/tsr';
Options.Location := 'Head Office';
// One call writes the timestamp, the DSS and the archive DocTimeStamp.
Pdf.SignPades('contract-lta.pdf', Options);
finally
Pdf.Free;
end;
end;
สำหรับขั้นตอนระดับ B-LT นั้น PDFium Component จะสร้างห่วงโซ่ใบรับรองด้วยฟังก์ชัน CertGetCertificateChain และเขียนพจนานุกรม /DSS เก็บใบรับรองของผู้เซ็นร่วมกับใบรับรอง CA ระดับกลางทั้งหมดในอาร์เรย์ /Certs (พร้อมด้วยอาร์เรย์ /OCSPs และ /CRLs ขนานกันไป) ควบคู่กับตัวระบุ /Extensions /ESIC ในระดับ 1 ตามที่กำหนดในข้อกำหนด EN 319 142-1 §5.4.2 ใบรับรองรากประเภทลงลายเซ็นด้วยตัวเองจะถูกละเว้นเนื่องจากข้อกำหนด RFC 5652 §10.2.3 อนุญาตให้ทำได้ และใบรับรองรากคือส่วนอ้างอิงที่ตัวตรวจสอบมีอยู่แล้ว ผลลัพธ์คือลายเซ็นที่โปรแกรมเปิดอ่านสามารถตรวจสอบความถูกต้องได้โดยอาศัยเพียงข้อมูลในตัวไฟล์เท่านั้น
สำหรับ B-LTA ตัวส่วนประกอบจะทำการเพิ่มระบุเวลาเอกสาร (Document Time-stamp): ซึ่งเป็นพจนานุกรมลายเซ็นที่มี /SubFilter /ETSI.RFC3161 โดยมีขอบเขต /ByteRange ครอบคลุมเนื้อหาไฟล์ทั้งหมด และมี /Contents เก็บโทเค็น RFC 3161 เหนือขอบเขตนั้น และปรับระดับ ESIC เป็นระดับ 2 นี่คือขั้นตอนการจัดเก็บข้อมูลจดหมายเหตุตามข้อกำหนด §5.4.3 และ TS 119 142-3 เนื่องจาก DocTimeStamp ครอบคลุมทั้งตัว DSS และตัวลายเซ็น จึงพิสูจน์ได้ว่าข้อมูลยืนยันความถูกต้องที่ฝังอยู่นั้นมีอยู่จริงและไม่ถูกแก้ไข ณ เวลาที่จัดเก็บข้อมูล ซึ่งเป็นสิ่งที่นโยบายการจัดเก็บเอกสารระยะยาวต้องการพิสูจน์
การอัปเกรดลายเซ็นที่มีอยู่แล้ว
ในบางกรณีมีลายเซ็นอยู่ในเอกสารแล้ว และคุณต้องการเพียงอัปเดตหรือเพิ่มข้อมูลยืนยันความถูกต้อง เช่น เพื่ออัปเกรดลายเซ็นระดับ B-B ของบริษัทอื่นให้เป็นระดับ B-LT สำหรับการเก็บรักษาระยะยาว PDFium Component แสดงฟังก์ชันแทรก DSS นี้ผ่านเมธอด SaveAsPadesDss ซึ่งจะแนบโครงสร้าง /DSS และ /Extensions ในรูปแบบการบันทึกแบบเพิ่มพูนโดยไม่แก้ไขไบต์ลายเซ็นเดิม
procedure AddValidationStore;
var
Pdf: TPdf;
DssOpts: TPadesDssOptions;
Cert: TPadesDssMaterial;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'already-signed.pdf';
Pdf.Active := True;
DssOpts := TPadesDssOptions.Default;
DssOpts.EsicExtensionLevel := 1; // 1 for B-LT, 2 for B-LTA
Cert.DerBytes := LoadSignerCertDer; // your DER-encoded certificate
SetLength(DssOpts.Certs, 1);
DssOpts.Certs[0] := Cert;
Pdf.SaveAsPadesDss('already-signed-lt.pdf', DssOpts);
finally
Pdf.Free;
end;
end;
คุณ supply ใบรับรองที่เข้ารหัสแบบ DER, และตัวเลือก OCSP responses และ CRLs ที่ตัวตรวจสอบความถูกต้องจะต้องการ ตั้งค่า EsicExtensionLevel เป็น 1 สำหรับคลังระดับ B-LT หรือ 2 เมื่อมี DocTimeStamp ตามมาด้วย ละเว้น IncludeVri ไว้ที่ค่าเริ่มต้นคือ False: ข้อกำหนด EN 319 142-1 §5.4.2.3 ระบุว่าพจนานุกรม /VRI ของแต่ละลายเซ็นเป็นส่วนตัวเลือกเสริม และแนะนำให้เว้นไว้เว้นแต่ว่าโปรแกรมปลายทางเจาะจงของคุณจะต้องการใช้งาน
ข้อพิจารณาและขอบเขตการทำงานที่ควรวางแผนล่วงหน้า
มีข้อจำกัดสามประการที่ควบคุมการใช้งานระดับมาตรฐานเหล่านี้ ประการแรกคือ โครงสร้างคริปโตกราฟีรองรับเฉพาะบนระบบปฏิบัติการ Windows เท่านั้น: ขั้นตอนการเซ็นชื่อและระบุเวลาจะทำงานผ่านบริการ CNG และ WinHttp ของระบบ Windows ทำให้คุณสมบัติ PadesCryptoAvailable ส่งกลับค่า False บนระบบอื่น และ SignPades จะแสดงข้อผิดพลาด ส่วนความสามารถการตรวจสอบฝั่งอ่านข้อมูลที่นำเสนอในบทความตอนก่อนหน้านั้นสามารถทำงานได้ข้ามแพลตฟอร์ม มีเพียงขั้นตอนการเขียนลายเซ็นเท่านั้นที่จำกัดเฉพาะบน Windows ประการที่สองคือ ระดับ B-T และ B-LTA ขึ้นอยู่กับหน่วยงานรับรองเวลา (TSA) ซึ่งหมายความว่าจะต้องมีกระบวนการเชื่อมต่อเครือข่ายในเวลาเซ็นชื่อ และความพร้อมใช้งานและขีดจำกัดความเร็วของเซิร์ฟเวอร์ภายนอกจะกลายเป็นส่วนหนึ่งของพาธการเซ็นชื่อของคุณ
ประการที่สามคือ แต่ละระดับจะเพิ่มขนาดความจุของไฟล์ แต่ละขั้นตอนจะเป็นการบันทึกแบบเพิ่มพูนแทนที่จะเป็นการเขียนทับไฟล์เดิม, ตัว DSS จะฝังห่วงโซ่ใบรับรองเต็มรูปแบบ และระเบียน DocTimeStamp จะต้องจองพื้นที่ล่วงหน้าสำหรับเก็บข้อมูลโทเค็น ส่งผลให้ไฟล์ระดับ B-LTA มีขนาดใหญ่กว่าไฟล์ระดับ B-B อย่างเห็นได้ชัด นี่คือการแลกเปลี่ยนโดยเจตนา: คุณต้องยอมเสียขนาดไบต์ในปัจจุบันเพื่อแลกกับความสามารถการยืนยันข้อมูลได้ในอนาคต สำหรับงานสัญญาและข้อมูลข้อกำหนดส่วนใหญ่แล้วนี่เป็นทางเลือกที่คุ้มค่า แต่แนะนำให้ทดสอบวัดขนาดจากเอกสารจริงของคุณเพื่อการวิเคราะห์ที่ถูกต้อง เมื่อคุณต้องการตรวจสอบว่าไฟล์ผลลัพธ์บรรลุระดับเป้าหมายที่ต้องการจริงหรือไม่ สามารถตรวจสอบได้ด้วยเทคนิคในหัวข้อ inspecting PDF digital signatures and PAdES levels และหากคุณต้องการปรับปรุงเสถียรภาพของกระบวนการทำเอกสาร สามารถดูหัวข้อการตรวจสอบความปลอดภัยได้ใน auditing PDF security risks
ความสามารถการลงลายเซ็น PAdES, โครงสร้าง DSS และการระบุเวลาเอกสารจดหมายเหตุที่อธิบายในที่นี้เป็นส่วนหนึ่งของ PDFium Component สำหรับ Delphi และ C++Builder ซึ่งในหน้าผลิตภัณฑ์จะมีรายละเอียดอ้างอิงและข้อกำหนดของแพลตฟอร์มอย่างครบถ้วน