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

PHP7使用openssl_pkcs7_verify验证PDF数字签名报PEM错误求助

解决PHP7中openssl_pkcs7_verify验证PDF签名时出现的error:0906D06C错误

我来帮你分析下这个错误的原因和解决思路:

首先,你遇到的error:0906D06C:PEM routines:PEM_read_bio:no start line错误,本质是**openssl_pkcs7_verify函数把你的PDF文件当成了PEM格式的PKCS#7签名文件来解析,但PDF根本不是这种格式**。

错误根源

openssl_pkcs7_verify的设计初衷是验证PKCS#7格式的签名数据(比如单独的.p7s签名文件,或者带签名的邮件内容),它期望输入的文件是标准PEM格式——也就是开头有-----BEGIN PKCS7-----、结尾有-----END PKCS7-----标记的文件。而你的PDF文件里内嵌了数字签名,但整个文件本身并不是PKCS#7格式,所以函数尝试读取PEM头的时候自然找不到,就抛出了这个错误。

解决方案

要验证PDF的数字签名,不能直接把PDF文件丢给openssl_pkcs7_verify,得先处理PDF内部的签名结构,推荐两种方式:

  • 使用专业PDF库(更省心):比如TCPDF、mPDF或者专门的PDF签名验证库,这些工具已经封装了PDF签名的解析逻辑,能自动提取内嵌的PKCS#7签名数据并完成验证,不用你手动处理PDF结构。
  • 手动提取PKCS#7数据(适合自定义场景):如果你想自己实现,需要先解析PDF文件,找到签名字典里的Contents字段(这就是PKCS#7签名的二进制数据),然后把它转换成PEM格式保存为临时文件,再用openssl_pkcs7_verify验证这个临时文件。举个简化的示例:
// 第一步:从PDF中提取签名的Contents二进制数据(这里需要你自己实现PDF解析逻辑)
$pkcs7BinaryData = get_pdf_signature_contents('doc.pdf');

// 第二步:转换成PEM格式并保存为临时文件
$tempPemFile = tempnam(sys_get_temp_dir(), 'pdf_sign');
$pemContent = "-----BEGIN PKCS7-----\n" . chunk_split(base64_encode($pkcs7BinaryData)) . "\n-----END PKCS7-----";
file_put_contents($tempPemFile, $pemContent);

// 第三步:用openssl验证
$result = openssl_pkcs7_verify($tempPemFile, PKCS7_TEXT);
if (!$result) {
    echo openssl_error_string();
} else {
    echo "签名验证通过";
}

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

注意:get_pdf_signature_contents函数需要你自己实现,或者用PDF解析库来获取签名内容,直接解析PDF的话需要熟悉PDF的文件结构规范。

内容的提问来源于stack exchange,提问作者Henrique André

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:37:24