1. 文章
  2. 文章详情

用PHP从PDF中检索数字签名信息

一开始,请阅读关于AdobePDF中的数字签名的文章
其次,读完这个之后,你会知道签名被存储在b和c字节之间,根据/ ByteRange [a b c d]指示器
第三,我们可以从文档中提取b和c,然后提取签名本身(指导说它将是十六进制编码的PKCS7#对象)。

 $content = file_get_contents('test.pdf');
$regexp = '#ByteRange[(d+) (d+) (d+)#'; // subexpressions are used to extract b and c
$result = []; preg_match_all($regexp, $content, $result);
// $result[2][0] and $result[3][0] are b and c if (isset($result[2]) && isset($result[3]) && isset($result[2][0]) && isset($result[3][0])) { $start = $result[2][0]; $end = $result[3][0]; if ($stream = fopen('test.pdf', 'rb')) { $signature = stream_get_contents($stream, $end - $start - 2, $start + 1); // because we need to exclude < and > from start and end
fclose($stream); }
file_put_contents('signature.pkcs7', hex2bin($signature)); }

第四,在第三步之后,我们在文件signature.pkcs7中有PKCS#7对象。 不幸的是,我不知道使用PHP从签名中提取信息的方法。 所以你必须能够运行shell命令来使用openssl

openssl pkcs7 -in signature.pkcs7 -inform DER -print_certs > info.txt

在文件info.txt中运行此命令后,您将拥有一个证书链。 最后一个是你需要的。 你可以看到文件的结构并解析所需的数据。
有一个代码可以根据需要进行调整。

use ASN1TypeConstructedSequence;
use ASN1Element;
use X509CertificateCertificate; 

$seq = Sequence::fromDER($binaryData); $signed_data = $seq->getTagged(0)->asExplicit()->asSequence();// ExtendedCertificatesAndCertificates: https://tools.ietf.org/html/rfc2315#section-6.6 $ecac = $signed_data->getTagged(0)->asImplicit(Element::TYPE_SET)->asSet();// ExtendedCertificateOrCertificate: https://tools.ietf.org/html/rfc2315#section-6.5 $ecoc = $ecac->at($ecac->count() - 1); $cert = Certificate::fromASN1($ecoc->asSequence()); $commonNameValue = $cert->tbsCertificate()->subject()->toString(); echo $commonNameValue;

参考:如何用PHP从PDF中检索数字签名信息? - 问答 - 云+社区 - 腾讯云

发表评论

登录后才能评论

评论列表(0条)