Chữ ký nằm ở đâu trong tệp PDF
ISO 32000-2 §12.8 Spec: ETSI EN 319 142-1 ETSI EN 319 142-1 Spec: RFC 5652 RFC 5652 Evidence: Standard-backed
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Một chữ ký PDF không bọc bên ngoài tệp. Nó được nhúng bên trong tệp: một từ điển định danh chữ ký và một digest được tính trên dải byte đã khai báo, chủ ý bỏ qua chính giá trị chữ ký. Trang này giải thích cơ chế đó và, cũng quan trọng không kém, những điều nó không cam kết.
Vì sao điều này quan trọng
Phần tiêu đề “Vì sao điều này quan trọng”Câu “Tài liệu đã được ký” thường là cơ sở để mọi người ra quyết định. Họ gắn câu đó với một khoản thanh toán, một sự phê duyệt, một nghĩa vụ pháp lý. Nếu bạn không biết chính xác chữ ký bao phủ những byte nào, bạn không thể nói một kết quả hợp lệ thực sự chứng minh điều gì. Một tệp PDF có thể mang một chữ ký hoàn toàn hợp lệ mà vẫn hiển thị cho người đọc nội dung người ký chưa từng thấy, vì nội dung đó được thêm vào sau khi ký, trong một vùng mà chữ ký chưa bao giờ tuyên bố bao phủ. Biết rõ thẩm quyền của chữ ký bắt đầu và kết thúc ở đâu là khác biệt giữa một quyết định có cơ sở vững chắc và một quyết định chỉ dựa trên hy vọng.
Phiên bản ngắn gọn
Phần tiêu đề “Phiên bản ngắn gọn”- Một chữ ký PDF nằm trong một từ điển chữ ký và một trường chữ ký bên trong tài liệu, chứ không phải là lớp bọc bên ngoài.
- Các byte được ký được khai báo bằng một mảng
ByteRange: hai phân đoạn(offset, length)cùng nhau bao phủ toàn bộ tệp ngoại trừ giá trị chữ ký dạng thập lục phân được giữ trong mụcContents. - Digest của hai phân đoạn được nối lại đó là thứ mà chữ ký mật mã thực sự bảo vệ.
- Mọi thứ được thêm vào sau đó trong một bản sửa đổi mới đều nằm ngoài byte range ban đầu. Chữ ký ban đầu vẫn hợp lệ; nó chưa từng tuyên bố gì về các byte mới.
- Một chữ ký phê duyệt và một chữ ký chứng nhận khác nhau ở phạm vi: chứng nhận (DocMDP) ràng buộc những thay đổi nào được phép sau này; phê duyệt thì không.
Cách NextPDF tiếp cận điều này
Phần tiêu đề “Cách NextPDF tiếp cận điều này”NextPDF dựng chữ ký theo đúng mô hình của định dạng, theo một thứ tự cố định, để byte range chính xác chứ không chỉ gần đúng.
Khi engine ghi một chữ ký, trước tiên nó dành sẵn một vùng có kích thước cố định cho
giá trị Contents rồi ghi một chỗ giữ chỗ ByteRange có độ rộng cố định. Nó
chờ cho đến khi toàn bộ tài liệu được ghi xong, bao gồm cả bảng tham chiếu chéo
và dấu kết thúc tệp. Chỉ khi đó nó mới tính hai offset thực,
ghi chúng trở lại chỗ giữ chỗ mà không làm dịch chuyển bất kỳ byte nào, băm hai
phân đoạn, rồi đặt đối tượng CMS thu được vào vùng đã dành sẵn. Chỗ
giữ chỗ được đệm bằng số 0 đến một độ dài cố định, chính là để việc điền vào các
con số thực không thể làm dịch chuyển các byte đang được băm. Đây là thứ tự duy nhất
tạo ra một chữ ký nhất quán với chính nó. Engine xử lý mọi thất bại trong
trình tự này như một lỗi nghiêm trọng thay vì âm thầm dùng phương án dự phòng.
Với hồ sơ PDF 2.0, bản thân đối tượng chữ ký là một cấu trúc CMS tách rời
SignedData. Từ điển PDF cho biết ở đâu và như thế nào; đối tượng CMS
mang theo ai và bằng chứng mật mã.
- Step 1 of 4: ISO 32000-2 §12.8.1 — ByteRange digest & signature dictionary
- Step 2 of 4: ISO 32000-2 §12.8.3.3 — ETSI.CAdES.detached SubFilter
- Step 3 of 4: ETSI EN 319 142-1 PAdES baseline profile
- Step 4 of 4: RFC 5652 CMS SignedData in Contents
Bằng chứng nói gì
Phần tiêu đề “Bằng chứng nói gì” Evidence: Standard-backed Cơ chế này được định nghĩa bởi
Spec: ISO 32000-2, §12.8.1 ISO 32000-2 §12.8.1 . Một digest byte-range được
tính trên dải byte do mục ByteRange chỉ định. Dải đó
phải là toàn bộ tệp bao gồm từ điển chữ ký nhưng loại trừ
giá trị chữ ký — tức mục Contents. ByteRange là một mảng các
cặp số nguyên — offset bắt đầu và độ dài. Các dải không liền nhau được
dùng có chủ đích để digest có thể bỏ qua chính giá trị chữ ký.
Với hồ sơ PDF 2.0, Spec: ISO 32000-2, §12.8.3.3 ISO 32000-2 §12.8.3.3 quy định rằng khi SubFilter là ETSI.CAdES.detached, giá trị Contents là một đối tượng CMS SignedData được mã hóa DER — cùng cấu trúc
Spec: RFC 5652 RFC 5652 định nghĩa — và hồ sơ PAdES của đối tượng đó
chính là hồ sơ mà Spec: ETSI EN 319 142-1 ETSI EN 319 142-1 mô tả.
Phạm vi giữa các chữ ký không giống nhau. Spec: ISO 32000-2, §12.7.4.5 ISO 32000-2 §12.7.4.5 định nghĩa quyền MDP: giá trị 0 biến chữ ký thành chữ ký phê duyệt, trong khi các giá trị 1–3 biến nó thành chữ ký chứng nhận ràng buộc những sửa đổi nào về sau vẫn giữ tài liệu ở trạng thái tuân thủ. Cơ chế byte-range vẫn là một; cam kết cho tương lai thì khác.
Engine của NextPDF hiện thực hóa đúng mô hình này: một chỗ giữ chỗ ByteRange có độ rộng cố định, digest nối hai phân đoạn, và một đối tượng CMS tách rời trong một vùng Contents đã dành sẵn, chỉ được hoàn tất sau khi tệp hoàn chỉnh.
Ví dụ thực tế
Phần tiêu đề “Ví dụ thực tế”Bạn hiếm khi phải tự tay dựng một ByteRange. Mục đích của ví dụ là cho thấy hình dạng của kết quả để bạn nhận ra nó khi kiểm tra một tệp đã được ký.
<?php
declare(strict_types=1);
use NextPDF\Security\Signature\ByteRangeCalculator;
// Offsets the engine knows only after the whole PDF is written:// $contentsStart — byte just before the '<' of the hex signature// $contentsEnd — byte just after the '>' that closes it// $fileLength — total file size in bytes$range = ByteRangeCalculator::calculate( contentsStart: $contentsStart, contentsEnd: $contentsEnd, fileLength: $fileLength,);// $range === [0, $contentsStart, $contentsEnd, $fileLength - $contentsEnd]// Segment 1: file start → just before the signature value// Segment 2: just after the signature value → end of file// The signature value itself is the gap. It is never hashed.
$signedMessage = ByteRangeCalculator::extractSignedData($pdfBytes, $range);// $signedMessage is segment 1 concatenated with segment 2 — exactly the// bytes the cryptographic digest is computed over.Khoảng trống giữa hai phân đoạn chính là giá trị chữ ký. Nó không thể là một phần của digest của chính nó; đó là lý do dải gồm hai phần, chứ không phải một.
Hiểu lầm thường gặp
Phần tiêu đề “Hiểu lầm thường gặp”Cái bẫy nằm ở niềm tin rằng một chữ ký hợp lệ có nghĩa là toàn bộ tệp mà bạn đang xem chính là thứ đã được ký. Không phải vậy. Nó có nghĩa là các byte nằm trong dải đã khai báo còn nguyên vẹn. Một bản sửa đổi về sau có thể thêm nội dung một cách hợp lệ — một chữ ký thứ hai, dữ liệu biểu mẫu, vật liệu xác thực — ngoài dải đó. Chữ ký đầu tiên vẫn hợp lệ, và nó không nói gì về phần được thêm vào. Một trình xem đúng đắn sẽ cho bạn biết một chữ ký bao phủ “tài liệu ở trạng thái tồn tại tại thời điểm ký”, chứ không phải “mọi byte trên màn hình.” Đánh đồng hai điều này là cách một tài liệu đã ký có thể nhận thêm nội dung chưa ký nhưng vẫn trông như đã ký.
Giới hạn và ranh giới
Phần tiêu đề “Giới hạn và ranh giới”Trang này giải thích cấu trúc, chứ không phải sự tin cậy. Một
ByteRange được tạo đúng cùng đối tượng CMS cho bạn biết các byte còn nguyên vẹn và khóa nào đã ký
chúng. Tự thân chúng không cho bạn biết khóa đó có thuộc về đúng người mà bạn
nghĩ hay không, chứng chỉ của nó có hợp lệ tại thời điểm ký hay không, hoặc sau đó nó có bị
thu hồi hay không. Đó là phần việc của đường dẫn chứng chỉ và cơ chế thu hồi, được trình bày trong
Xác thực một chữ ký đúng cách.
Trang này cũng không giải quyết việc ký diễn ra khi nào bằng bất kỳ
thẩm quyền độc lập nào. Một thời điểm ký do bản thân tự khai báo không phải là thời gian đáng tin cậy —
xem Dấu thời gian và thời gian đáng tin cậy.
NextPDF dựng cấu trúc được mô tả ở đây; còn các chứng chỉ, trust anchor,
và cơ quan cấp dấu thời gian do triển khai của bạn cung cấp, chứ không phải engine.
Theo từng cấp độ, engine cung cấp khả năng dựng cấu trúc như sau:
| Edition | Availability |
|---|---|
| Core | PAdES B-B: từ điển chữ ký, ByteRange có độ rộng cố định, và đối tượng CMS SignedData tách rời được mô tả trên trang này. |
| Pro | Thêm PAdES B-T — một dấu thời gian đáng tin cậy trên giá trị chữ ký — trên cùng cấu trúc đó. |
| Enterprise | Thêm các hồ sơ dài hạn (B-LT, B-LTA): vật liệu xác thực được nhúng và dấu thời gian tài liệu được xếp chồng trên cùng nền tảng byte-range. |
Tài liệu liên quan
Phần tiêu đề “Tài liệu liên quan”- Cập nhật tăng dần và vì sao chúng quan trọng — vì sao việc thêm vào, thay vì viết lại, là điều giữ cho byte range của chữ ký đầu tiên còn nguyên vẹn.
- Hồ sơ cơ sở PAdES — những gì được xếp chồng lên trên cấu trúc này, và nghĩa vụ nào cần đến hồ sơ nào.
- Xác thực dài hạn — cách nhúng bằng chứng xác thực để một chữ ký vẫn có thể kiểm chứng được trong nhiều năm.
Thuật ngữ
Phần tiêu đề “Thuật ngữ”- Từ điển chữ ký — từ điển PDF đặt tên cho bộ xử lý chữ ký,
SubFilter,ByteRangevà giá trịContents. ByteRange— một mảng các cặp số nguyên(offset, length)khai báo chính xác các byte mà digest của chữ ký bao phủ.Contents— mục thập lục phân chứa giá trị chữ ký (với PDF 2.0, là một đối tượng CMSSignedDatatách rời); nó bị loại trừ khỏi chính digest của mình.- CMS
SignedData— cấu trúc Cryptographic Message Syntax (RFC 5652) chứa chứng chỉ của người ký và các byte chữ ký. - PAdES — PDF Advanced Electronic Signatures: hồ sơ ETSI của chữ ký CMS cho PDF, được định nghĩa trong bộ tiêu chuẩn ETSI EN 319 142.
- Chữ ký phê duyệt — một chữ ký có quyền
MDP0; nó xác nhận nội dung mà không ràng buộc những thay đổi về sau. - Chữ ký chứng nhận — một chữ ký có quyền DocMDP (
MDP1–3) quy định những sửa đổi nào về sau vẫn giữ tài liệu ở trạng thái tuân thủ.