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é
相关产品推荐
相关产品推荐

