PDFファイルに添付された)デジタル署名からデータ(署名者名)を取得する必要があるアプリがあります。
JavaおよびC#で、iTextクラスのAcroFieldsメソッドGetSignatureNamesを使用した例のみを見つけました
編集: dump_data_fieldsとgenerate_fpdfでpdftkを試しましたが、結果は(残念ながら)次のとおりでした:
/Fields [
<<
/V /dftk.com.lowagie.text.pdf.PdfDictionary@3048918
/T (Signature1)
>>]
そして
FieldType: Signature
FieldName: Signature1
FieldFlags: 0
FieldJustification: Left
前もって感謝します !
まあ、PHPだけでこれを達成するのは複雑です(私は不可能とさえ言いますが、誰が知っているでしょうか)。
まず、お読みください Adobe PDFのデジタル署名に関する記事
次に、これを読んだ後、署名が/ ByteRange [a b c d]インジケータに従ってbバイトとcバイトの間に格納されていることがわかります
3番目に、ドキュメントからbとcを抽出してから、署名自体を抽出できます(ガイドでは、16進数にデコードされたPKCS7#オブジェクトになると述べています)。
<?php
$content = file_get_contents('test.pdf');
$regexp = '#ByteRange\[\s*(\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));
}
4番目に、3番目のステップの後、ファイルsignature.pkcs7にPKCS#7オブジェクトがあります。残念ながら、PHPを使用して署名から情報を抽出する方法はわかりません。したがって、opensslを使用するには、シェルコマンドを実行できる必要があります。
openssl pkcs7 -in signature.pkcs7 -inform DER -print_certs > info.txt
ファイルinfo.txtでこのコマンドを実行すると、証明書のチェーンが作成されます。最後はあなたが必要なものです。ファイルの構造を確認し、必要なデータを解析できます。
この質問 、 この質問 および このトピック も参照してください
EDIT at 2017-10-09私は故意に表示することをお勧めしました 正確にこの質問 調整できるコードがありますあなたの要望。
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;
調整しましたが、残りはご自身でお作りください。
私はiTextを使用しましたが、非常に信頼できることがわかりましたので、強くお勧めします。 PHPからJavaコードを「マイクロサービス」としていつでも呼び出すことができます。