Pas d'inquiétude, avec PBAdonf, c'est dans la poche ! ^^

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.

#1 29-07-2015 14:23:05

ydl  
Membre Geek
Date d'inscription: 23-10-2007
Messages: 62
Pépites: 10,341
Banque: 0

[RESOLU] PDF signé

Bonjour,
Je cherche à signer les pdf dans powerbuilder.
Pour ce faire , je suis partie sur la piste de ItextSharp (http://sourceforge.net/projects/itextsharp/)
J'ai récupéré une application en C#, j'en ai extrait le code qui m'intéresse et j'ai compilé le tout en com assembly que j'ai enregistré avec regsam.
Mon problème est que le connecttonewobject me retourne toujours -3
J'ai mis le code c#, je tiens à préciser que je suis une bille en C#
J'ai du louper un truc a moins que Pb 11.5 ne fonctionne pas avec les assembly donet
Quelqu'un a-t-il déjà signer un pdf avec PB ?

Code PB

Code: pb

    oleobject      loo  
    integer          li_rc  
    string            ls_orgfilename, ls_encfilename  
    string            ls_orgpathname, ls_encpathname  
    string            ls_extension = "PDF"  
    string            ls_filter = "PDF files (*.pdf),*.pdf"  
     IF GetFileOpenName ( "Select PDF file to encrypt", ls_orgpathname, ls_orgfilename, ls_extension, ls_filter ) = 1 THEN  
        IF GetFileSaveName ( "Specify filename for encrypted file", ls_encpathname, ls_encfilename, ls_extension, ls_filter ) = 1 THEN  
            loo = create oleobject  
            li_rc = loo.ConnectToNewObject ( "ItextWrapper2.ItextWrapper2" )  
    Messagebox('test',string(li_rc))
//            loo.encrypt ( ls_orgpathname, ls_encpathname )  
//            loo.DisconnectObject()  
            destroy loo  
        END IF  
    END IF

Code c#

Code: c#

using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;

namespace ItextWrapper2
{
    public class ItextWrapper2
    {
        public string KEYSTORE = @"C:\Users\ydulondel\AppData\Roaming\Adobe\Acrobat\11.0\Security\narval.pfx";
        public string KEYSTORE_PUB = @"D:\test\pub\CertExchangenarval.fdf";
        // public const String KEYSTORE = @"..\..\resources\text\pdf\signature\ds-ks\cert2.pfx";
        public string PASSWORD = "password";
        // public const String Src = @"..\..\resources\text\pdf\signature\xfa.pdf";
        public string Src;
        public string Dst;

        public const string HashAlg = "SHA1";
        public const string SignAlg = "SHA-1withRSA";

        private class SignatureDTO
        {
            public byte[] Hash { get; set; }
            public PdfSignatureAppearance SignatureAppearance { get; set; }
            public PdfPKCS7 Sign { get; set; }
            public DateTime Now { get; set; }
            public Stream Stream { get; set; }
        }

        private AsymmetricKeyEntry LoadCertificateChainFromKeyStorage()
        {
            MemoryStream ks = new MemoryStream();
            using (FileStream reader = new FileStream(KEYSTORE, FileMode.Open))
            {
                byte[] buffer = new byte[reader.Length];
                reader.Read(buffer, 0, (int)reader.Length);
                ks.Write(buffer, 0, buffer.Length);
                ks.Position = 0;
            }
            Pkcs12Store store = new Pkcs12Store(ks, PASSWORD.ToCharArray());
            String alias = "";
            List<X509Certificate> chain = new List<X509Certificate>();
            // searching for private key

            foreach (string al in store.Aliases)
            {
                if (store.IsKeyEntry(al) && store.GetKey(al).Key.IsPrivate)
                {
                    alias = al;
                    break;
                }
            }

            foreach (X509CertificateEntry c in store.GetCertificateChain(alias)) // may be return too
                chain.Add(c.Certificate);

            AsymmetricKeyEntry pk = store.GetKey(alias);
            return pk;
            //return chain;
        }

        public void SignTest(String pKeyStore, String pKeyStorePub, String pPassword, String pPdf, String pSignPdf)
        {
            this.KEYSTORE = pKeyStore;
            this.KEYSTORE_PUB = pKeyStorePub;
            this.PASSWORD = pPassword;
            this.Src = pPdf;
            this.Dst = pSignPdf;
            SignatureDTO result = ServerSidePrepare();
            byte[] signedData = ClientSideSign(result.Hash);
            SaveSignedDocumentOnServer(result, signedData);
        }

        private SignatureDTO ServerSidePrepare()
        {
            // get public key chain
            X509Certificate cert = new X509CertificateParser().ReadCertificate(
                File.ReadAllBytes(KEYSTORE_PUB)); // &#1089;&#1077;&#1088;&#1074;&#1077;&#1088; &#1091; &#1085;&#1072;&#1089; &#1080; &#1090;&#1072;&#1082; &#1080;&#1084;&#1077;&#1077;&#1090; &#1087;&#1091;&#1073;&#1083;&#1080;&#1095;&#1085;&#1099;&#1081; &#1082;&#1083;&#1102;&#1095; &#1087;&#1086;&#1083;&#1100;&#1079;&#1086;&#1074;&#1072;&#1090;&#1077;&#1083;&#1103;

            PdfReader reader = new PdfReader(Src); // &#1089;&#1095;&#1080;&#1090;&#1072;&#1077;&#1084; &#1095;&#1090;&#1086; &#1092;&#1072;&#1081;&#1083; &#1087;&#1077;&#1088;&#1077;&#1076; &#1087;&#1086;&#1076;&#1087;&#1080;&#1089;&#1100;&#1102; &#1077;&#1089;&#1090;&#1100; &#1085;&#1072; &#1089;&#1077;&#1088;&#1074;&#1077;&#1088;&#1077;
                                                   // MemoryStream ms = new MemoryStream();
                                                   // var ms = File.Create(Dst);
            FileStream os = new FileStream(Dst, FileMode.Create);
            PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');

            PdfSignatureAppearance sap = stamper.SignatureAppearance;
            sap.Reason = "reason";
            sap.Location = "location";
            sap.Certificate = cert;

            sap.SetVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");

            PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);

            dic.Reason = sap.Reason;
            dic.Location = sap.Location;
            dic.Contact = sap.Contact;
            // dic.Date = new PdfDate(sap.SignDate);
            dic.Date = new PdfDate(new DateTime(2015, 7, 26, 17, 5, 25));

            sap.CryptoDictionary = dic;

            Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>
            {
                { PdfName.CONTENTS, 8192 * 2 + 2 }
        // &#1085;&#1077; &#1087;&#1086;&#1076;&#1087;&#1080;&#1089;&#1099;&#1074;&#1072;&#1077;&#1084;&#1099;&#1077; &#1076;&#1072;&#1085;&#1085;&#1099;&#1077; (&#1080;&#1089;&#1082;&#1083;&#1102;&#1095;&#1077;&#1085;&#1080;&#1103;). &#1047;&#1072;&#1074;&#1080;&#1089;&#1080;&#1090; &#1086;&#1090; &#1090;&#1086;&#1075;&#1086;, &#1074;&#1085;&#1077;&#1076;&#1088;&#1077;&#1085;&#1099; &#1083;&#1080; CRL &#1080; &#1086;&#1090;&#1074;&#1077;&#1090;&#1099; OCSP &#1074; &#1076;&#1086;&#1082;&#1091;&#1084;&#1077;&#1085;&#1090;&#1077;.
        // PdfName.CONTENTS &#1079;&#1076;&#1077;&#1089;&#1100; &#1076;&#1086;&#1083;&#1078;&#1077;&#1085; &#1073;&#1099;&#1090;&#1100; &#1086;&#1073;&#1103;&#1079;&#1072;&#1090;&#1077;&#1083;&#1100;&#1085;&#1086; 
      };

            sap.PreClose(exc);

            var sgn = new PdfPKCS7(null, new[] { cert }, HashAlg, false);

            Stream data = sap.GetRangeStream();
            // byte[] hash = DigestAlgorithms.Digest(data, externalDigest.getMessageDigest("SHA256"));
            byte[] messageHash = DigestAlgorithms.Digest(data, HashAlg); // hash calculated. Sending it to client.
            var now = DateTime.Now;
            return new SignatureDTO
            {
                Hash = sgn.getAuthenticatedAttributeBytes(messageHash, now, null, null, CryptoStandard.CMS),
                Now = now,
                SignatureAppearance = sap,
                Sign = sgn,
                Stream = os
            };
        }

        private byte[] ClientSideSign(byte[] hash)
        {
            AsymmetricKeyEntry pk = LoadCertificateChainFromKeyStorage();

            // we sign the hash received from the server
            ISigner sig = SignerUtilities.GetSigner(SignAlg);
            sig.Init(true, pk.Key);
            sig.BlockUpdate(hash, 0, hash.Length);
            return sig.GenerateSignature();
        }

        private void SaveSignedDocumentOnServer(SignatureDTO result, byte[] signature)
        {
            result.Sign.SetExternalDigest(signature, null, "RSA");
            byte[] encodedSig = result.Sign.GetEncodedPKCS7(result.Hash, result.Now, null, null, null, CryptoStandard.CMS);

            byte[] paddedSig = new byte[8192];
            Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);

            PdfDictionary pdfDic = new PdfDictionary();
            pdfDic.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true));

            result.SignatureAppearance.Close(pdfDic); // use try/catch in real app
        }
    }
}

Dernière modification par ydl (30-07-2015 09:45:34)

Hors ligne

 

#2 30-07-2015 07:35:41

Van  
Bienfaiteur du site
Award: bf
Lieu: mouvaux
Date d'inscription: 19-03-2013
Messages: 125
Pépites: 673
Banque: 41

Re: [RESOLU] PDF signé

Pour que ta dll soit disponible en objet com tu doit déclarer des interfaces pour chacunes de tes methodes public disponible en com via ton objet.

Il manque aussi un [ComVisible(true)] avant le début de ta classItextWrapper2 que doit récupérer le contrat d'interface.

Tu dois aussi utiliser une clé dans un fichier .snk (je ne me rappel plus trop la façon de faire car je l'ai utilisé qu'une seule fois en début d'année).

Tu peux regarder le dépôt github de ma dll com pour web services. J'ai utiliser visual studio 2012 et j'utilise la dll via une appli PB12.6 mais ça doit pas poser de problème de l'utiliser via PB 11.5.

Bref y'a encore un peu de boulot mais ça reste gentil. Une fois que ce sera fait tu pourra utiliser ta Dll via l'objet COM.


Tant que ça bouge c'est pas mort, dans le doute frappe encore!
Ni dieu ni maître, sauf maître Kanter!

Hors ligne

 

#3 30-07-2015 07:37:45

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: [RESOLU] PDF signé

est-ce que tu as bien toutes les dll des dépendances (bouncycastle etc.) à ton assembly .net accessibles par ton assembly ?

Hors ligne

 

#4 30-07-2015 09:45:14

ydl  
Membre Geek
Date d'inscription: 23-10-2007
Messages: 62
Pépites: 10,341
Banque: 0

Re: [RESOLU] PDF signé

En fouillant un peu , j'ai trouvé
En modifiant le code

Code:

using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System.Runtime.InteropServices;

namespace ItextWrapper2
{

        [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
        public interface ComClass1Interface
        {
        }

        [Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),
            InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface ComClass1Events
        {
        }

        [Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
            ClassInterface(ClassInterfaceType.None),
            ComSourceInterfaces(typeof(ComClass1Events))]

    public class ItextWrapper2 : ComClass1Interface
    {
        public string KEYSTORE =

J'ai un retour a 0 maintenant

Hors ligne

 

#5 31-07-2015 07:58:02

ydl  
Membre Geek
Date d'inscription: 23-10-2007
Messages: 62
Pépites: 10,341
Banque: 0

Re: [RESOLU] PDF signé

Je n'avais pas vu vos réponses.
Merci

Hors ligne

 

Pied de page des forums

Propulsé par FluxBB 1.2.22