2 votes

C# - Obtenir une clé publique à partir d'une signature PDF

Le cas d'utilisation est le suivant :

  1. L'utilisateur entre sur un site web qui requiert la présentation d'un certificat.
  2. S'il est valide, l'utilisateur peut télécharger un PDF et le signer avec le même certificat.
  3. Chargement du PDF
  4. Le serveur valide que le PDF est signé par le même certificat que celui qui présente le site web.

Je suis bloqué à l'étape 4. J'ai réussi à obtenir la clé publique du certificat du client à partir du site web et aussi à partir du PDF, mais ce ne sont pas les mêmes. La clé publique est un SHA256 RSA de 2048 bits. De plus, j'utilise iTextSharp pour manipuler les documents PDF.

Voici mon code :

 HttpRequest request = context.Request;

 HttpClientCertificate cert = request.ClientCertificate;

 //get public key from client certificate
 string certKey = BitConverter.ToString(cert.PublicKey).Replace("-", " ")

 //now gets PDF and retrieves public key
 PdfReader pdfreader = new PdfReader("path_to_pdf");

 AcroFields fields = pdfreader.AcroFields;
 AcroFields.Item item = fields.GetFieldItem("Signature1");
 List<string> names = fields.GetSignatureNames();

 foreach (string name in names){
     PdfDictionary dict = fields.GetSignatureDictionary(name);
     PdfPKCS7 pkcs7 = fields.VerifySignature(name);
     Org.BouncyCastle.X509.X509Certificate cert = pkcs7.SigningCertificate;

     //get public key from PDF cert
     SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cert.GetPublicKey());
     byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
     string serializedPublic = BitConverter.ToString(serializedPublicBytes).Replace("-", " ");
 }

Avec ce code, certKey et serializedPublic ne sont pas les mêmes.

1voto

mkl Points 13928

Dans votre code, vous comparez

  • la valeur binaire de la clé publique du certificat ( HttpClientCertificate.PublicKey ) avec
  • la valeur binaire d'un SubjectPublicKeyInfo objet ( publicKeyInfo.ToAsn1Object().GetDerEncoded() ) qui englobe la clé publique et son algorithme.

On peut donc s'attendre à ce que ces derniers contiennent la première mais ne pas coïncider avec elle.

A SubjectPublicKeyInfo est défini comme suit :

SubjectPublicKeyInfo ::= SEQUENCE {
    algorithm AlgorithmIdentifier,
    publicKey BIT STRING
}

Au lieu de comparer avec la représentation binaire de l'image complète SubjectPublicKeyInfo vous devez donc le comparer avec la représentation binaire de la clé publique contenue :

publicKeyInfo.PublicKeyData.GetBytes()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X