Security
Security
本页涵盖密码、加密和数字签名。Document.OpenFile() / Document.Open() 接受密码以打开受保护的文档,Document.Save() 接受 encrypt 选项来保护文档,且 Document.Sign() / Document.Certify() / Document.VerifySignatures() 添加并检查数字签名。
打开并解密受密码保护的文档
将 { password: '...' } 传递给 Document.OpenFile() 或 Document.Open() 以打开受用户密码保护的文档。如果密码缺失或错误,调用会抛出 InvalidPasswordError。
import { Document, InvalidPasswordError } from '@asposefoss/pdf';
try {
const doc = Document.OpenFile('secret.pdf', { password: 'hunter2' });
doc.WriteTo('decrypted.pdf'); // output is plaintext
} catch (e) {
if (e instanceof InvalidPasswordError) console.error('wrong password');
else throw e;
}保存时加密
Document.Save()(以及 Document.WriteTo())接受一个 encrypt 选项。基于密码的加密是常见情况;库还支持使用公钥对一个或多个接收者证书进行加密,随后使用接收者的私钥再次打开。
// Encrypt to one or more recipient certificates (PEM string or DER bytes):
const bytes = doc.Save({
encrypt: {
recipients: [{ certificate: recipientCertPem }],
algorithm: 'aes256', // 'aes256' (default) | 'aes128' | 'rc4'
permissions: { copying: false }, // shared across all recipients
},
});
// Open with the recipient's private key + certificate, or a PKCS#12 bundle:
const opened = Document.Open(bytes, {
recipient: { privateKey, certificate: recipientCertPem },
});
console.log(opened.Permissions); // recovered permission flags (not enforced)
签名与认证
Document.Certify() 添加一个认证(作者)签名,携带一个 DocMDP 转换,声明后续允许的更改;Document.Sign() 添加另一个普通的批准签名,可以在其上增量追加。两者都接受一个 { certificate, privateKey } 签署者和一个选项对象(reason、location、name、fieldName,以及——针对 Certify()——permissions)。
const certifying = Document.OpenFile('report.pdf');
await certifying.Certify(
{ certificate: author.certificate, privateKey: author.privateKey },
{ permissions: 'form-fill', reason: 'Certifying the report', fieldName: 'Certification' },
);
const certifiedBytes = certifying.Save();
const approving = Document.Open(certifiedBytes);
await approving.Sign(
{ certificate: approver.certificate, privateKey: approver.privateKey },
{ reason: 'Approved for publication', fieldName: 'Approval' },
);
approving.WriteTo('signed.pdf');验证签名
Document.VerifySignatures() 检查文档中的每个签名:它重新计算每个 /ByteRange 摘要,验证分离的 CMS,并报告每个签名之后的更改。它返回一个 SignatureReport[],每个签名对应一个条目。
const reports = await Document.OpenFile('signed.pdf').VerifySignatures();
for (const r of reports) {
console.log(r.name, 'integrity:', r.integrity, 'signature:', r.signature);
}技巧与最佳实践
- 在打开不可信输入时,先专门捕获
InvalidPasswordError,再使用更广泛的捕获,这样可以对错误密码和损坏文件作出不同的响应。 - 在任何
Sign()调用之前先调用Certify()—— 认证签名确定了后续批准签名所叠加的 DocMDP 权限。 Document.Open()在公钥解密后返回恢复的Permissions,但库本身并不强制执行它们 —— 将其视为信息性数据。VerifySignatures()是async—— 在读取报告数组之前await它(或处理返回的Promise)。
常见问题
| 问题 | 原因 | 修复 |
|---|---|---|
Document.OpenFile() / Document.Open() 抛出 InvalidPasswordError | 文档受密码保护,但未提供密码或提供了错误的密码 | 将 { password: '...' } 传递给 Document.OpenFile() / Document.Open() |
| 公钥解密失败 | 传递了错误的私钥或证书,或两者均未匹配加密时使用的任何 recipients 条目 | 确认 recipient 选项的 privateKey / certificate(或 PKCS#12 捆绑)与原始收件人之一匹配 |
| 批准签名会使认证失效 | Sign() 被调用时使用了认证 DocMDP 转换不允许的权限 | 在 Certify() 上设置一个 permissions 值(例如 'form-fill'),足够宽松以容纳后续签署者将进行的更改 |
VerifySignatures() 报告完整性检查失败 | 签名后的字节被修改,超出了签名所覆盖的增量更新范围 | 在进行任何进一步编辑后重新签署文档 |
FAQ
Sign 与 Certify 有何区别?
Certify() 添加第一个认证签名,并通过 DocMDP 转换声明后续允许的更改。Sign() 添加普通批准签名,逐步追加在之前的内容之上。
如何打开受密码保护的 PDF?
将 { password: '...' } 传递给 Document.OpenFile() 或 Document.Open(),如果密码可能错误,则捕获 InvalidPasswordError。
此库是否强制执行 PDF 权限标志?
不。Document.Open() 从加密文档中恢复 Permissions 标志供您检查,但它本身并不限制您的代码对打开的文档可以执行的操作。
我该如何检查已签名的 PDF 的签名是否仍然有效?
调用 Document.VerifySignatures() (an async method) 并检查每个返回的 SignatureReport 的 integrity 和 signature 字段。
API Reference 摘要
| 类/方法 | 描述 |
|---|---|
Document.OpenFile() / Document.Open() | 打开文档,可选密码或公钥保护 |
InvalidPasswordError | 当密码缺失或错误时抛出 |
Document.Save() / Document.WriteTo() | 保存文档,可选使用 encrypt 选项 |
Permissions | 从加密文档中恢复的权限标志 |
Document.Certify() | 添加带有 DocMDP 转换的认证(作者)签名 |
Document.Sign() | 添加批准签名 |
Document.VerifySignatures() | 验证文档中的每个签名 |
SignatureReport | 单个签名的验证结果:name、integrity、signature |