Cách Bảo mật và Ký tài liệu PDF trong TypeScript
Hướng dẫn này chỉ cách mã hoá, chứng nhận, ký và xác minh tài liệu PDF bằng Aspose.PDF FOSS cho TypeScript. Document.Save() và Document.Open() xử lý mã hoá khóa công khai tới chứng chỉ người nhận, trong khi Document.Certify(), Document.Sign() và Document.VerifySignatures() xử lý chữ ký số kiểu PAdES. Yêu cầu Node.js 22 hoặc phiên bản mới hơn.
Hướng dẫn từng bước
Bước 1: Cài đặt gói
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-TypeScript.git
cd Aspose.PDF-FOSS-for-TypeScript
npm install
npm run buildXác minh việc cài đặt bằng cách nhập lớp Document vào một tệp TypeScript mới — dòng này sẽ được giải quyết mà không có lỗi khi gói đã được cài đặt:
import { Document } from '@asposefoss/pdf';Bước 2: Nhập các lớp cần thiết
Nhập Document để mở, lưu, ký và xác minh tệp; các bước ký và mã hóa bên dưới truyền các đối tượng tùy chọn thuần, vì vậy không cần nhập thêm gì nữa:
import { Document } from '@asposefoss/pdf';Bước 3: Mã hóa tài liệu cho các chứng chỉ người nhận
Document.Save() chấp nhận một tùy chọn encrypt chứa một hoặc nhiều recipients, mỗi cái được xác định bằng một chứng chỉ (chuỗi PEM hoặc byte DER), một algorithm, và permissions chung:
const doc = Document.OpenFile('report.pdf');
const bytes = doc.Save({
encrypt: {
recipients: [{ certificate: recipientCertPem }],
algorithm: 'aes256', // 'aes256' (default) | 'aes128' | 'rc4'
permissions: { copying: false }, // shared across all recipients
},
});Bước 4: Mở một tài liệu đã được mã hóa
Truyền một tùy chọn recipient cho Document.Open() kèm theo khóa riêng và chứng chỉ tương ứng, hoặc một gói PKCS#12:
const opened = Document.Open(bytes, {
recipient: { privateKey, certificate: recipientCertPem },
// or: recipient: { pkcs12: p12Bytes, passphrase: '…' },
});
console.log(opened.Permissions); // recovered permission flags (not enforced)
Bước 5: Chứng nhận và ký một tài liệu
Document.Certify() và Document.Sign() đều hoạt động bất đồng bộ và nhận một danh tính (certificate + privateKey) cùng các tùy chọn mô tả trường chữ ký, giao diện và lý do. Việc chứng nhận nên được thực hiện đầu tiên, trên toàn bộ tệp; các chữ ký phê duyệt tiếp theo được thêm vào một cách tăng dần sau đó:
async function certifyAndSign(sourcePath: string, signaturePageIndex: number): Promise<void> {
const certifying = Document.OpenFile(sourcePath);
await certifying.Certify(
{ certificate: authorCert, privateKey: authorKey },
{
permissions: 'form-fill',
reason: 'Certifying the document',
fieldName: 'Certification',
appearance: { page: signaturePageIndex, rect: [400, 100, 550, 140] },
},
);
const certifiedBytes = certifying.Save();
const approving = Document.Open(certifiedBytes);
await approving.Sign(
{ certificate: approverCert, privateKey: approverKey },
{ reason: 'Approved for publication', fieldName: 'Approval', subFilter: 'PAdES' },
);
approving.WriteTo('signed.pdf');
}Bước 6: Xác minh các chữ ký
Document.VerifySignatures() là bất đồng bộ và trả về một SignatureReport cho mỗi trường chữ ký, mỗi cái báo cáo integrity mật mã, tính hợp lệ của signature, và liệu nó coversWholeFile:
async function verify(path: string): Promise<void> {
const doc = Document.OpenFile(path);
const reports = await doc.VerifySignatures();
for (const r of reports) {
console.log(`${r.name}: integrity=${r.integrity} signature=${r.signature} `
+ `coversWholeFile=${r.coversWholeFile} docMDP=${r.docMDP}`);
}
}Các vấn đề thường gặp và cách khắc phục
Document.Sign() / Document.Certify() ném hoặc treo. Cả hai đều bất đồng bộ — await cuộc gọi. Quên await để lại promise trả về chưa được giải quyết và việc ghi diễn ra trước khi ký hoàn tất.
Chữ ký phê duyệt sau này làm cho chứng chỉ không còn hiệu lực. Ký dần: lưu các byte đã chứng nhận trước tiên (certifying.Save()), mở lại chúng bằng Document.Open(), sau đó gọi Sign() trên tài liệu đã mở lại đó — việc viết lại toàn bộ thay vì một phép nối tăng dần làm hỏng chứng nhận của /ByteRange bản tóm tắt.
VerifySignatures() reports coversWholeFile: false cho chữ ký đầu tiên nhưng true cho chữ ký cuối cùng. Điều này là mong đợi cho một chuỗi certify-then- sign: chứng nhận đã được ký trước khi phê duyệt được nối thêm, vì vậy chỉ có chữ ký mới nhất của /ByteRange mở rộng tới cuối tệp.
Giải mã thất bại với khóa riêng đúng. Xác nhận certificate được truyền tới recipient khớp với chứng chỉ chính xác mà tài liệu đã được mã hoá tới trong Document.Save()của recipients danh sách — một chứng chỉ được cấp lại với cặp khóa mới sẽ không giải mã được dữ liệu đã được mã hoá bằng cặp khóa cũ.
Câu hỏi thường gặp
Một tài liệu có thể được mã hóa cho nhiều hơn một người nhận không?
Có — recipients trong tùy chọn encrypt của Document.Save() chấp nhận một mảng; bất kỳ khóa riêng khớp nào của người nhận đều có thể mở tệp kết quả.
Định dạng chữ ký mà Document.Sign() tạo ra là gì?
Việc đưa subFilter: 'PAdES' vào các tùy chọn ký tạo ra một chữ ký tương thích PAdES; nếu bỏ qua thì sẽ sử dụng bộ lọc phụ chữ ký mặc định của thư viện.
Làm sao tôi kiểm tra xem một tài liệu có được chứng nhận hay chỉ được ký?
Kiểm tra trường docMDP trên SignatureReport do Document.VerifySignatures() trả về — một chữ ký chứng nhận báo cáo một phán quyết quyền DocMDP; một chữ ký chỉ chấp nhận không có.
Các Permissions đã khôi phục sau Document.Open() có được thư viện thực thi không?
Không — opened.Permissions báo cáo các cờ quyền được ghi trong tệp đã mã hóa để kiểm tra; việc thực thi chúng trong một ứng dụng là trách nhiệm của người gọi.