ข้ามไปยังเนื้อหา

การตรวจสอบลายเซ็นให้ถูกต้อง

Spec: RFC 5280, §6 Spec: RFC 6960 Spec: RFC 5652 Evidence: Test-backed

“ลายเซ็นถูกต้อง” โดยทั่วไปมักหมายถึงการตรวจสอบเพียงเรื่องเดียว คือการคำนวณทางคณิตศาสตร์สอดคล้องกัน การตรวจสอบความถูกต้องที่ครบถ้วนต้องตรวจสอบประเด็นที่เป็นอิสระต่อกันอย่างน้อยห้าข้อ และข้อใดข้อหนึ่งอาจล้มเหลวในแบบที่ทำให้เครื่องหมายถูกสีเขียวหมดความหมาย หน้านี้นำเสนอชุดการตรวจสอบทั้งหมดและอธิบายว่าเหตุใดคำตอบที่ไม่สมบูรณ์จึงเป็นคำตอบที่อันตราย

ค่า boolean เพียงค่าเดียวเป็นเอาต์พุตที่อันตรายที่สุดในหัวข้อนี้ เพราะทำให้ผู้อ่านตีความ “ถูกต้อง” ว่าเป็น “น่าเชื่อถือ” ทั้งที่ “ถูกต้อง” อาจหมายถึงเพียงว่าไบต์ไม่ถูกแก้ไข และลายเซ็นตรวจสอบผ่านด้วยคีย์จากใบรับรองที่หมดอายุไปแล้วเมื่อสามปีก่อน ถูกเพิกถอนไปเมื่อเดือนที่แล้ว และเชื่อมโยงไปยังหน่วยงานที่คุณไม่รู้จัก แต่ละเรื่องเป็นการตรวจสอบที่แยกจากกัน ซอฟต์แวร์ที่รายงานค่า boolean เพียงค่าเดียวได้ตัดสินใจแบบเงียบ ๆ ไปแล้วว่าการตรวจสอบใดสำคัญ และตัดสินใจแทนคุณ ในบริบทที่อยู่ภายใต้การกำกับดูแลหรือสัญญา “เครื่องมือบอกว่าถูกต้อง” ไม่ใช่ข้อแก้ตัว หากเครื่องมือนั้นตรวจสอบเฉพาะคุณสมบัติที่มีต้นทุนต่ำที่สุด

การตรวจสอบความถูกต้องที่ครบถ้วนต้องตอบคำถามห้าข้อที่แยกจากกัน คำถามเหล่านี้เป็นอิสระต่อกัน การผ่านข้อหนึ่งไม่ได้บอกอะไรเกี่ยวกับข้ออื่น ๆ

  1. ความถูกต้องครบถ้วน — ไบต์ที่ลงนามยังแฮชได้ตรงกับสิ่งที่ลายเซ็นครอบคลุมอยู่หรือไม่ (คำนวณ digest ของช่วงไบต์ใหม่และเปรียบเทียบ)
  2. ความเป็นของแท้ — ลายเซ็นเชิงการเข้ารหัสลับตรวจสอบผ่านด้วยคีย์สาธารณะในใบรับรองที่ใช้ลงนาม โดยครอบคลุม signed attributes หรือไม่
  3. เส้นทางใบรับรอง — ใบรับรองนั้นเชื่อมโยงไปยัง trust anchor ที่ คุณ เลือก และทุกจุดเชื่อมต่อถูกต้องหรือไม่
  4. เวลา — ใบรับรองอยู่ภายในช่วงอายุการใช้งาน ณ เวลาที่เกี่ยวข้อง หรือไม่ และเวลานั้นเป็นเวลาที่น่าเชื่อถือ ไม่ใช่เวลาที่ผู้ลงนามอ้างเองหรือไม่
  5. การเพิกถอน — ใบรับรอง ไม่ถูกเพิกถอน ณ เวลานั้นหรือไม่ โดยอ้างอิงหลักฐาน (OCSP/CRL) ที่คุณสามารถเข้าถึงได้จริงหรือที่ฝังมาด้วย

“ถูกต้อง” ที่ไม่ได้ตรวจครบทั้งห้าข้อคือคำตอบที่ไม่สมบูรณ์ซึ่งดูเหมือนคำตอบที่สมบูรณ์

จุดยืนของ NextPDF คือคำถามแต่ละข้อแยกจากกันและต้องได้รับคำตอบอย่างชัดเจน คำถามเหล่านี้จะไม่ถูกยุบรวมเป็นแฟล็กเชิงบวกเพียงค่าเดียว และจะไม่ถูกข้ามแบบเงียบ ๆ เพียงเพราะตรวจสอบไม่สะดวก สิ่งนี้บังคับใช้ด้วยการทดสอบ นั่นคือเหตุผลที่หน้านี้ระบุว่า test-backed แทนที่จะเป็น standard-backed กล่าวคือพฤติกรรมถูกยึดไว้ด้วยชุดทดสอบ ไม่ใช่เพียงการอ้างจากข้อกำหนดเท่านั้น

ความถูกต้องครบถ้วนและความเป็นของแท้ได้รับการทดสอบแบบครบวงจร โดยใช้ใบรับรองที่ทราบอยู่แล้วลงนามในโครงสร้าง signed-attributes จริง และชุดทดสอบตรวจสอบลายเซ็นด้วยคีย์สาธารณะที่ตรงกัน ครอบคลุมเวกเตอร์เวลาหลายค่า ดังนั้นการเปลี่ยนแปลงที่ทำให้โครงสร้างมาตรฐานเสียหายจะทำให้การทดสอบล้มเหลว การตรวจสอบความถูกต้องของเส้นทางใบรับรองถูกยึดไว้ด้วยการทดสอบที่จงใจดัดแปลงไบต์ของลายเซ็นและยืนยันว่าผลลัพธ์ ไม่ ถูกต้อง พร้อมเหตุผลที่มีโครงสร้าง ผลลัพธ์นั้นไม่ใช่ข้อยกเว้นที่ถูกทิ้งไป แต่เป็นความล้มเหลวที่ถูกบันทึกไว้อย่างชัดเจน การตรวจสอบ timestamp-token ถูกแยกเป็นขั้นตอนย่อย ได้แก่ การถอดรหัส ข้อมูลผู้ลงนาม signed attributes message digest การผูกใบรับรอง key usage ลายเซ็น และ produced-at และแต่ละขั้นตอนได้รับการทดสอบแยกกัน ดังนั้น “timestamp ผ่านการตรวจสอบ” จึงหมายความว่าทุกขั้นตอนผ่านการตรวจสอบ ความล้มเหลวแบบ soft ในการตรวจสอบการเพิกถอน (responder ที่ไม่สามารถเข้าถึงได้) ถูกแยกออกจากผลลัพธ์ “ถูกเพิกถอน” ที่ชัดเจนทั้งในโค้ดและในการทดสอบ ทั้งสองกรณีจะไม่ถูกรวมเป็นคำตอบเดียวกัน

  1. Integrity Recompute the byte-range digest and compare it to the value the signature covers.
  2. Authenticity Verify the cryptographic signature against the certificate’s public key, over the signed attributes — not the raw content.
  3. Certificate path Build and validate the chain to a trust anchor you chose; every link’s signature, validity, and constraints must hold.
  4. Time Confirm the certificate was valid at the relevant instant, and that the instant is trusted time, not the signer’s clock.
  5. Revocation Confirm the certificate was not revoked at that time, using obtainable or embedded OCSP/CRL evidence.
คำถามที่เป็นอิสระต่อกันห้าข้อที่การตรวจสอบความถูกต้องของลายเซ็น PDF ที่ถูกต้องจะตอบ ตามลำดับ แต่ละข้อแยกจากกัน การผ่านข้อหนึ่งไม่ได้บอกอะไรเกี่ยวกับข้ออื่น และการข้ามข้อใดข้อหนึ่งทำให้ผลลัพธ์โดยรวมไม่สมบูรณ์

Evidence: Test-backed พฤติกรรมถูกยึดไว้ด้วยการทดสอบ และ การทดสอบเหล่านั้นนำข้อกำหนดของมาตรฐานไปปฏิบัติ

ความถูกต้องครบถ้วนอ้างอิง Spec: ISO 32000-2, §12.8.1 โดยคำนวณ digest ใหม่ครอบคลุมช่วงไบต์แล้วเปรียบเทียบกับค่าที่จัดเก็บไว้ ความแตกต่างใด ๆ หมายความว่าลายเซ็นไม่ถูกต้อง ความเป็นของแท้ที่ครอบคลุม signed attributes มี integration test รองรับ โดยลงนามชุด signed-attributes จริงและตรวจสอบด้วยคีย์สาธารณะที่ตรงกัน ครอบคลุมเวกเตอร์เวลาหลายค่า คำถามเกี่ยวกับเส้นทางใบรับรองคือ Spec: RFC 5280, §6.1 : เส้นทางที่ถูกต้องเริ่มต้นจาก trust anchor และ Spec: RFC 5280, §6.2 ระบุว่าอัลกอริทึมนั้น กำหนดเงื่อนไข ขั้นต่ำ สำหรับเส้นทางที่จะถือว่าถูกต้อง โดย unit test ของตัวตรวจสอบเส้นทาง ยืนยันว่าลายเซ็นที่ถูกดัดแปลงมีผลลัพธ์เป็น valid = false พร้อมด้วย เหตุผลที่ชัดเจน ไม่ใช่การยอมรับแบบเงียบ ๆ

ลำดับการตรวจสอบการเพิกถอนอ้างอิง Spec: RFC 6960, §3.2 กล่าวคือก่อนที่ไคลเอ็นต์จะยอมรับการตอบกลับการเพิกถอนที่ลงนามว่าถูกต้อง ไคลเอ็นต์ SHALL ยืนยันว่าลายเซ็นของการตอบกลับนั้นถูกต้องและผู้ลงนามได้รับอนุญาตในปัจจุบัน และ Spec: RFC 6960, §4.2.2.2 กำหนดให้การอนุญาตนั้นเป็นการมอบหมาย id-kp-OCSPSigning ที่ออกโดยตรงจาก CA ที่เกี่ยวข้อง ดังนั้นคำตอบเรื่องการเพิกถอนที่ยังไม่ได้ตรวจสอบความถูกต้องของตัวคำตอบเองกับผู้ลงนามที่ได้รับอนุญาตและตรวจสอบได้จึงไม่มีความหมาย การตรวจสอบการผูกใบรับรองคือ Spec: RFC 5035, §5.4.2 กล่าวคือหากแฮชของใบรับรองในแอตทริบิวต์ signing-certificate-v2 ที่ลงนามไม่ตรงกับใบรับรองที่ใช้ตรวจสอบลายเซ็น ลายเซ็น ต้อง ถือว่าไม่ถูกต้อง สิ่งนี้ปิดช่องโหว่การแทนที่ที่ทำให้ลายเซ็นตรวจสอบผ่านกับใบรับรองที่ผู้โจมตีเลือก ตัวโทเค็น timestamp เองได้รับการตรวจสอบในรูปแบบ Spec: RFC 5652 ในฐานะอ็อบเจกต์ CMS ทีละขั้นตอน โดยแต่ละขั้นตอนได้รับการทดสอบแยกกัน

ส่วนที่ควรเรียนรู้ไม่ใช่การเรียกใช้ API แต่เป็น คำถามที่คุณต้องสามารถตอบได้ ก่อนนำผลลัพธ์ไปใช้ตัดสินใจ จงถือว่านี่เป็นรายการตรวจสอบที่การตรวจทานจะใช้กำกับคุณ

<?php
declare(strict_types=1);
// A correct validation produces a structured outcome, not one boolean.
// Before you trust a signature, you must be able to answer ALL of these:
//
// integrity : Does the byte-range digest still match? (tamper check)
// authenticity: Does the signature verify over the SIGNED ATTRIBUTES,
// not just the content?
// path : Does the certificate chain to a trust anchor YOU chose,
// with every link valid at the relevant time?
// time : Is the relevant time TRUSTED (a timestamp), or merely the
// signer's self-asserted clock?
// revocation : Was the certificate not revoked at that time, by evidence
// you obtained or that the document embedded?
//
// "valid: true" without an answer to every line above is an incomplete
// result. A path-validation outcome carries a `valid` flag AND a structured
// `reasons` list precisely so a failure says WHY — never a bare false.

หากบรรทัดใดตอบได้เพียงว่า “ฉันไม่ทราบ” สถานะที่ซื่อสัตย์ย่อมไม่ใช่ “ถูกต้อง” แต่เป็น “ยังไม่ได้กำหนด” การมองสองสถานะนี้ว่าเหมือนกันคือข้อผิดพลาดที่หน้านี้ต้องการป้องกัน

กับดักแรกคือการตีความว่า “ถูกต้องในเชิงการเข้ารหัสลับ” เท่ากับ “น่าเชื่อถือ” ความถูกต้องครบถ้วนและความเป็นของแท้รวมกันพิสูจน์ได้เพียง ว่าไบต์เหล่านี้ถูกลงนามโดยผู้ถือคีย์นี้ สองสิ่งนี้ไม่ได้บอกเลยว่าใบรับรองของคีย์นั้นได้รับความเชื่อถือ ยังใช้งานได้อยู่ หรือไม่ถูกเพิกถอน เอกสารที่ลงนามด้วยใบรับรองที่สร้างขึ้นเองสามารถ “ถูกต้องในเชิงการเข้ารหัสลับ” และไม่มีค่าใด ๆ เลย กับดักอีกด้านหนึ่งคือการมองการตรวจสอบการเพิกถอนที่ ไม่อาจชี้ขาด (responder ออฟไลน์) ว่าเป็น การผ่าน หรือ การไม่ผ่าน ทั้งที่ไม่ใช่ทั้งสองอย่าง แต่เป็นสถานะที่ไม่ทราบ ตัวตรวจสอบที่ถูกต้องจะรายงานว่าไม่ทราบแทนที่จะคาดเดาไปทางใดทางหนึ่ง เครื่องหมายถูกสีเขียวที่ซ่อนว่าการตรวจสอบใดในห้าข้อถูกดำเนินการจริงนั้นไม่ใช่ผลการตรวจสอบความถูกต้อง แต่เป็นการตัดสินใจที่ผู้อื่นทำแทนคุณ

NextPDF ดำเนินการและทดสอบการตรวจสอบเชิงโครงสร้างและเชิงการเข้ารหัสลับ แต่ไม่ได้เลือก trust anchor ของคุณหรือรับประกันนโยบายที่อยู่นอกเหนือจากนั้น การที่คุณเชื่อถือใบรับรอง ใด เป็นการตัดสินใจระดับการนำไปใช้งานที่เอนจินไม่สามารถทำแทนได้ ห่วงโซ่ที่ตรวจสอบผ่านไปยัง anchor ที่คุณไม่ควรเชื่อถือยังคงเป็นผลการตรวจสอบความถูกต้องที่พึ่งพาไม่ได้ หลักฐานการเพิกถอนตรวจสอบได้ก็ต่อเมื่อเข้าถึงได้หรือฝังมาด้วยเท่านั้น responder ที่ออฟไลน์ให้ผลลัพธ์เป็น “ไม่อาจชี้ขาด” และการแปลงผลนั้นเป็นคำตัดสินคือทางเลือกเชิงนโยบาย ไม่ใช่หน้าที่ของเอนจิน หน้านี้อธิบายชุดการตรวจสอบ ไม่ใช่ความเพียงพอทางกฎหมาย การที่ลายเซ็นที่ผ่านการตรวจสอบความถูกต้องจะมีผลทางกฎหมายเฉพาะเรื่องหรือไม่ ขึ้นอยู่กับใบรับรอง ผู้ลงนาม เขตอำนาจศาล และข้อผูกพัน วิธีที่หลักฐานที่ฝังมาช่วยให้ยังตอบการตรวจสอบเหล่านี้ได้เมื่อเวลาผ่านไปกล่าวถึงใน การตรวจสอบความถูกต้องระยะยาว ส่วนกลไกช่วงไบต์ที่อยู่เบื้องหลังการตรวจสอบความถูกต้องครบถ้วนอยู่ใน ลายเซ็นอยู่ในไฟล์ PDF อย่างไร

ความพร้อมใช้งานของพื้นผิวการตรวจสอบความถูกต้องตามระดับ:

การตรวจสอบความถูกต้องของลายเซ็น — edition availability
Edition Availability
Core

ความถูกต้องครบถ้วนและความเป็นของแท้ที่ครอบคลุม signed attributes พร้อมกับการตรวจสอบความถูกต้องของเส้นทางใบรับรองตาม RFC 5280 §6 เทียบกับ trust anchor ที่จัดเตรียมไว้

Pro

เพิ่มการตรวจสอบ timestamp-token ตาม RFC 3161 ซึ่งเป็นคำถามเรื่องเวลาที่น่าเชื่อถือ ที่แยกย่อยเป็นขั้นตอนซึ่งตรวจสอบอย่างเป็นอิสระต่อกัน

Enterprise

เพิ่มการประเมินการเพิกถอน (OCSP/CRL) และการตรวจสอบความถูกต้องเทียบกับวัสดุ ระยะยาวที่ฝังมา โดยแยกผลลัพธ์ที่ไม่อาจชี้ขาดออกจาก ผลลัพธ์ที่ชี้ขาดได้

  • การตรวจสอบความถูกต้องครบถ้วน — การคำนวณ digest ของช่วงไบต์ใหม่แล้วเปรียบเทียบกับค่าที่ลายเซ็นครอบคลุม
  • การตรวจสอบความเป็นของแท้ — การตรวจสอบลายเซ็นเชิงการเข้ารหัสลับเทียบกับคีย์สาธารณะของใบรับรองที่ใช้ลงนาม โดยครอบคลุม signed attributes
  • Signed attributes — แอตทริบิวต์ CMS ที่ถูกลงนาม (content-type, message-digest, signing-time, signing-certificate-v2) ที่ลายเซ็นถูกคำนวณครอบคลุมจริง
  • การตรวจสอบความถูกต้องของเส้นทางใบรับรอง — การสร้างและตรวจสอบห่วงโซ่จากใบรับรองที่ใช้ลงนามไปยัง trust anchor ที่เลือกไว้ (RFC 5280 §6)
  • Trust anchor — หน่วยงานออกใบรับรองที่คุณตัดสินใจเชื่อถือ ซึ่งเป็นรากของเส้นทางที่ยอมรับได้
  • การตรวจสอบการเพิกถอน — การพิจารณาว่าใบรับรองถูกเพิกถอน ณ เวลาที่เกี่ยวข้องหรือไม่ โดยใช้ OCSP หรือ CRL
  • ไม่อาจชี้ขาด — ผลลัพธ์การเพิกถอนที่ไม่ใช่ทั้ง “ดี” และ “ถูกเพิกถอน” เพราะไม่สามารถเข้าถึงหลักฐานได้ จึงไม่ใช่การผ่านและไม่ใช่การไม่ผ่าน