You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中验证TCPDF签名的PDF是否匹配指定公私密钥

TCPDF签名PDF的密钥匹配验证方法

核心流程说明

整个验证分两个核心环节:先从已签名PDF中提取待校验的原始数据$data和签名值$signature,再用你持有的公钥做签名匹配校验。

步骤1:提取$signature和$data参数

推荐使用SetaPDF组件解析PDF结构,也可以自行解析PDF字典实现,示例代码如下:

// 引入SetaPDF核心组件(可通过composer require setasign/setapdf-core安装)
require_once 'vendor/autoload.php';

$pdfPath = '你要验证的已签名PDF路径';
// 加载PDF文件
$parser = new \SetaPDF_Core_Parser_Pdf($pdfPath);
$document = $parser->getDocument();
// 获取表单中的签名字段(TCPDF默认签名字段名为Signature)
$form = $document->getCatalog()->getAcroForm();
$signatureFields = $form->getFieldsByName('Signature');

$signature = '';
$data = '';
foreach ($signatureFields as $field) {
    $sigDict = $field->getValue();
    // 提取签名值:转成二进制格式,得到$signature参数
    $signatureHex = trim($sigDict->getValue('Contents')->getValue(), '<>');
    $signature = hex2bin($signatureHex);

    // 提取待签名原始数据:按ByteRange指定的范围读取PDF字节,得到$data参数
    $byteRange = $sigDict->getValue('ByteRange')->toPhp();
    $fh = fopen($pdfPath, 'rb');
    for ($i = 0; $i < count($byteRange); $i += 2) {
        fseek($fh, $byteRange[$i]);
        $data .= fread($fh, $byteRange[$i + 1]);
    }
    fclose($fh);
    break; // 仅验证第一个签名,多签名场景可自行扩展
}

步骤2:用公钥验证签名匹配性

使用PHP内置的openssl扩展做PKCS7签名校验即可,不需要用到私钥:

// 写入临时文件供openssl函数调用
$tempDataFile = tempnam(sys_get_temp_dir(), 'pdf_verify');
file_put_contents($tempDataFile, $data);

$tempSigFile = tempnam(sys_get_temp_dir(), 'pdf_sig');
// 把二进制签名转成PEM格式
$pemSign = "-----BEGIN PKCS7-----\n" . chunk_split(base64_encode($signature), 64, "\n") . "-----END PKCS7-----\n";
file_put_contents($tempSigFile, $pemSign);

// 你的公钥文件路径
$publicKeyPath = 'file://' . realpath('你的公钥.pem');
// 执行验证:返回1为匹配,0为不匹配,-1为执行错误
$verifyResult = openssl_pkcs7_verify(
    $tempDataFile,
    PKCS7_BINARY | PKCS7_NOVERIFY | PKCS7_NOCHAIN, // 仅校验签名归属,不校验证书有效性
    $tempSigFile,
    [],
    $publicKeyPath
);

// 清理临时文件
unlink($tempDataFile);
unlink($tempSigFile);

if ($verifyResult === 1) {
    echo '验证通过:该PDF为对应密钥签名';
} else {
    echo '验证失败:签名不匹配或文件被篡改';
}

注意:如果你的公钥是DER格式,需要先转成PEM格式再传入验证函数。

内容的提问来源于stack exchange,提问作者Vitalicus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:06:06