嗯,它很複雜(我甚至說不可能,但是誰知道)只能用PHP來實現這一點。
首先,請閱讀article about digital signature in Adobe PDF
其次,看完這個你就知道簽名存儲b和c字節根據/ BYTERANGE [ABCD]指示燈
第三,我們可以提取和B之間c從文檔中提取簽名本身(指導說它將是十六進制編碼的PKCS7#對象)。
<?php
$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,你將有一個證書鏈後。最後一個是你需要的。你可以看到文件的結構並解析所需的數據。
請同時參閱this question,this question和this topic
編輯在2017年10月9日 明知勸你看到exactly this question 有,您可以調整您需要的代碼。
use ASN1\Type\Constructed\Sequence;
use ASN1\Element;
use X509\Certificate\Certificate;
$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;
我已經爲你調整過了,但請自行完成。
你看過fdf函數嗎? –
如果解決方案@Dennis發佈,不適合你然後讓我知道,我想給這個問題一個鏡頭 –
你有沒有考慮添加c代碼作爲php的擴展? – Nitin