我们使用 FPDI 将带有状态信息的额外页面附加到传入的 PDF 文档中。为此,我们将现有 PDF 加载为模板,然后添加一个新页面,在其中可以找到必要的状态信息。不幸的是,除了向 PDF 添加额外的页面之外,没有其他方法可以进一步传输这些状态信息。
我们现在偶然发现了一些加密的 PDF。您可以在任何 PDF 查看器和浏览器中正确打开这些 PDF。但是 FPDI 不支持加载加密的 PDF,我们的代码因错误而停止:
此 PDF 文档已加密,无法使用 FPDI 处理
我想在处理之前解密那些无需输入密码即可查看的 PDF。在我看来,有两种方法:
你觉得怎么样?还有更好的想法吗? 我将不胜感激! 谢谢。
使用 SetaPDF-Core 可以对加密/受保护的 PDF 文档进行身份验证:
$document = SetaPDF_Core_Document::loadByFilename('encrypted.pdf');
要检查文档是否已加密,您只需检查安全处理程序即可:
$isEncrypted = $document->hasSecHandler();
根据此信息,您可以访问安全处理程序:
if ($isEncrypted) {
// get the security handler
$secHandler = $document->getSecHandler();
// authenticate with a password without knowing if it is the owner or user password:
if ($secHandler->auth('a secret password')) {
echo 'authenticated as ' . $secHandler->getAuthMode();
} else {
echo 'authentication failed - neither user nor owner password did match.';
}
// authenticate with the user password:
if ($secHandler->authByUserPassword('a secret password')) {
echo 'authenticated as user';
} else {
echo 'authentication failed with the user password.';
}
// authenticate with the owner password:
if ($secHandler->authByOwnerPassword('a secret password')) {
echo 'authenticated as owner';
} else {
echo 'authentication failed with the owner password.';
}
}
(如果文档使用公钥加密,也可以使用私钥和证书 - 有关更多信息,请参阅此处)
如果您被验证为所有者,则可以从文档中删除安全处理程序:
if ($secHandler->getAuthMode() === SetaPDF_Core_SecHandler::OWNER) {
$document->setSecHandler(null);
$writer = new SetaPDF_Core_Writer_File('not-encrypted.pdf');
$document->setWriter($writer);
$document->save()->finish();
}
如果您使用 Fpdi,您可以在添加文件之前检查文件权限。此函数可以确定文件是否受保护。
function isPdfProtected($pdfPath) {
try {
// Try to read the file usng FPDI
$pdf = new \setasign\Fpdi\Fpdi();
$pageCount = $pdf->setSourceFile($pdfPath);
return false; // file not protected
} catch (\Exception $e) {
// the file is protected
if (strpos($e->getMessage(), 'encrypted') !== false) {
return true;
}
// another exceptions
return false;
}
}
您可以在添加文件之前检查文件权限。