2017-09-26 5 views
19

J'ai une application qui a besoin de récupérer certaines données (nom du signataire) de la signature numérique "attaché" sur les fichiers PDF.Comment récupérer des informations de signature numérique à partir de PDF avec PHP?

J'ai trouvé que des exemples en Java et C# en utilisant la méthode AcroFields classe iText GetSignatureNames

modifier: J'ai essayé pdftk avec dump_data_fields et generate_fpdf et le résultat était que (malheureusement):

/Fields [ 
<< 
/V /[email protected] 
/T (Signature1) 
>>] 

et

FieldType: Signature 
FieldName: Signature1 
FieldFlags: 0 
FieldJustification: Left 

Tha nks à l'avance!

+2

Avez-vous regardé les fonctions fdf? –

+0

Si la solution @Dennis posté, ne fonctionne pas pour vous alors laissez-moi savoir et je voudrais donner une réponse à cette question –

+0

Avez-vous envisagé d'ajouter le code c comme une extension de php? – Nitin

Répondre

13

Eh bien, c'est compliqué (je dirais même impossible, mais qui sait) pour y parvenir uniquement avec PHP.

Dans un premier temps, s'il vous plaît lire article about digital signature in Adobe PDF

En second lieu, après avoir lu ce que vous savez que la signature est enregistrée entre b et c octets selon/ByteRange indicateur

Troisième [abcd], nous pouvons extraire b et c à partir du document, puis extraire la signature elle-même (le guide dit que ce sera l'objet PKCS7 # hexdécodé). En outre, après la troisième étape, nous avons l'objet PKCS # 7 dans le fichier signature.pkcs7. Malheureusement, je ne connais pas les méthodes pour extraire des informations de la signature en utilisant PHP. Vous devez donc être en mesure d'exécuter des commandes shell pour utiliser OpenSSL

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

Après avoir exécuté cette commande dans le fichier info.txt vous aurez une chaîne de certificats. Le dernier est celui dont vous avez besoin. Vous pouvez voir la structure du fichier et analyser les données nécessaires.

S'il vous plaît se référer également à this question, this question et this topic

EDIT au 09/10/2017 Je vous conseille de voir en connaissance de cause exactly this question Il y a un code que vous pouvez adapter à vos besoins.

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; 

Je l'ai ajusté pour vous, mais s'il vous plaît faites le reste par vous-même.

+0

malheureusement le preg_match_all échoue à ce pdf avec ma signature: https://www.docdroid.net/oVB1AW2/ – celsowm

+1

@celsown Pourquoi vous n'avez pas pris la peine de jeter un oeil au contenu de votre fichier test.pdf? Votre indicateur ByteRange est un peu différent, vous avez juste besoin de changer légèrement '$ regexp = '#ByteRange \ s * \ [(\ d +) (\ d +) (\ d +) #';' –

+0

la nouvelle regex a fonctionné, merci. Maintenant, j'essaie d'utiliser PHPASN1 pour décoder le DER car apparemment PHP openssl ne fonctionne pas avec DER – celsowm

0

J'ai utilisé iText et je l'ai trouvé très fiable, je le recommande fortement. vous pouvez toujours appeler le code java comme un "microservice" de PHP.