Signatures are now supported in iText. See http://itextpdf.sf.net.

Best Regards,
Paulo Soares

> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On 
> Behalf Of Bruno
> Sent: Tuesday, August 31, 2004 1:52 PM
> To: J_OSES
> Cc: [EMAIL PROTECTED]
> Subject: [iText-questions] Re: PDF signature
> 
> Quoting J_OSES <[EMAIL PROTECTED]>:
> 
> > 
> > Hello,
> > 
> > I'm trying to post this message in the itext-
> > [EMAIL PROTECTED], but server seems to refuse 
> me all the 
> > time.
> 
> You are not subscribed.
> Do you want me to try subscribing you?
> 
> > Is it possible to post this message in the itext mailling list.
> 
> See CC: address.
> 
> > Thank you, very much, and I sorry for the disturbance.
> 
> No problem,
> br,
> Bruno
> 
> > Cheers,
> > juan
> > 
> > --------------------------------
> > 
> > 
> > Hi all,
> > 
> > I'm trying to use iText library and the Bouncy Castle Java 
> Suite (BC)
> > to embed digital signatures in a PDF file. Unfortunately I 
> wasn't very
> > lucky by the time. The main problem I have at the moment is
> > to verify the digital signature of a PDF file and a 
> signature generated
> > with the BC classes. I send the piece of code that tries to do that.
> > 
> > public class SignProblem {
> > 
> > String messagetxt = new String("Hello World!");
> > String pdfdoc;
> > Document doc;
> > String sub_detached = "adbe.pkcs7.detached";
> > String sub_sha1                 = "adbe.pkcs7.sha1";
> > 
> > public SignProblem(String pdfd)
> > {
> >        this.doc = null;
> >        this.pdfdoc = pdfd;
> >        // Provider added
> >        Security.addProvider(
> >                       new
> > org.bouncycastle.jce.provider.BouncyCastleProvider());
> > 
> >        }
> > 
> > public static void main(String[] args) {
> >        SignProblem pdfsign;
> >        int idx = 0;
> >        StringBuffer pathbuff = null;
> >        try {
> >                if (idx == args.length) {
> >                        System.out.println("PDFSign: missing
> > path to PDF file");
> >                        return;
> >                }
> >                pathbuff = new StringBuffer(args[idx++]);
> >                for (;idx<args.length;idx++)
> >                        pathbuff.append(" ").append(args[idx]);
> >                               Document doc = new Document();
> >                pdfsign = new SignProblem(pathbuff.toString());
> >                pdfsign.init(doc);
> >                                             } catch (Exception ex) {
> >                ex.printStackTrace();
> >        }
> >        }
> > 
> > private boolean init(Document doc) {
> >        String strDigest = CMSSignedDataGenerator.DIGEST_SHA1;
> >        byte[] contentbytes = new byte[0];
> >        Certificate[] certs = null;
> >        Collection certList = new ArrayList();
> >               try {
> >                this.doc = doc;
> >             PdfWriter writer = PdfWriter.getInstance(doc,new
> > FileOutputStream(pdfdoc));
> >        PdfAcroForm acroform = writer.getAcroForm();
> >        doc.addTitle("Michael Hall test signed PDF");
> >        doc.addSubject("PDF format iText signed document");
> >        doc.addKeywords("iText, DSA" );
> >        doc.addCreator("iText");
> >        doc.addAuthor("Michael Hall");
> >        doc.addHeader("Expires", "0");
> >        doc.open();
> >               KeyStore keyStore = KeyStore.getInstance("PKCS12");
> >        keyStore.load(new FileInputStream("josefernandez.pfx"),
> > storepswd);
> >        Provider provider = keyStore.getProvider();
> > 
> >        for(Enumeration e = keyStore.aliases() ;
> > e.hasMoreElements() ;) {
> >                alias = e.nextElement().toString();
> >        }
> > 
> >        // Retrieving private key
> >        PrivateKey privKey = (PrivateKey)keyStore.getKey(alias,
> > storepswd);
> >        java.security.cert.X509Certificate cert =
> > (java.security.cert.X509Certificate)keyStore.getCertificate(alias);
> > 
> >        java.security.cert.Certificate[] certChain =
> >                keyStore.getCertificateChain(alias);
> >               certs = new Certificate[] { cert };
> >        // getting the Certificates
> >  for ( int i = 0; i < certs.length;i++)
> >  {
> >                certList.add(certs[i]);       }
> >  CertStore cstore = CertStore.getInstance("Collection",
> > new CollectionCertStoreParameters(certList), "BC");
> >                                                   
> >        CMSProcessable msg = new CMSProcessableByteArray
> > (messagetxt.getBytes());
> >        CMSSignedDataGenerator gen = new CMSSignedDataGenerator
> > ();
> > 
> >        PdfSignature signature = new PdfSignature
> > ("Adobe.PPKMS");
> >        signature.setSubFilter(sub_sha1);
> >        signature.setString("Name","Michael Hall");
> >        //signature.addToAcroForm(acroform);
> >        PdfAcroForm acroForm = writer.getAcroForm();
> > 
> >          BaseFont bf = BaseFont.createFont
> > (BaseFont.HELVETICA,BaseFont.CP1252,BaseFont.NOT_EMBEDDED);
> >        Font displayfont = new Font(bf,11,Font.BOLD);
> >        Phrase p = new Phrase(messagetxt,displayfont);
> >        doc.add(p);
> >               RandomAccessFile raf = new 
> RandomAccessFile(pdfdoc,"r");
> >        byte[] docdata = new byte[(int)raf.length()];
> >        raf.readFully(docdata);
> >        raf.close();
> >                       raf = new 
> RandomAccessFile("dumpPart1.dat","r");
> >        byte[] docdata1 = new byte[(int)raf.length()];
> >        raf.readFully(docdata1);
> >        raf.close();
> > 
> >        RandomAccessFile raf2 = new RandomAccessFile
> > ("dumpPart2.dat","r");
> >        byte[] docdata2 = new byte[(int)raf2.length()];
> >        raf2.readFully(docdata2);
> >        raf2.close();
> >                       int strlength = docdata1.length + 
> docdata2.length;
> >        docdata = new byte[strlength];
> > 
> >        System.arraycopy(docdata1, 0, docdata, 0,
> > docdata1.length);
> >        System.arraycopy(docdata2, 0, docdata, docdata1.length,
> > docdata2.length);
> > 
> >        // ...                               CMSProcessable 
> cmsdata = 
> > new CMSProcessableByteArray
> > (docdata);
> >        gen = new CMSSignedDataGenerator();
> > 
> >        gen.addSigner(privKey,(X509Certificate)
> > cert,CMSSignedDataGenerator.DIGEST_SHA1);
> >        cstore = CertStore.getInstance("Collection",
> >                      new CollectionCertStoreParameters
> > (certList), "BC");
> >        gen.addCertificatesAndCRLs(cstore);
> >        CMSSignedData s = gen.generate(cmsdata, false, "BC");
> > 
> > // After signing data, I retrieve certificates from the 
> PKCs#7 object
> > to verify, that it's correct.
> > // This is the easy part and looks fine, :)
> > 
> > 
> >                                           CertStore certstore = 
> > s.getCertificatesAndCRLs
> > ("Collection", "BC");
> >        SignerInformationStore  signers = s.getSignerInfos();
> >        Collection              c = signers.getSigners();
> >        Iterator                it = c.iterator();
> > 
> >        while (it.hasNext())
> >        {
> >               SignerInformation   signer = 
> (SignerInformation)it.next
> > ();
> >               Collection          certCollection =
> > certstore.getCertificates(signer.getSID());
> > 
> >               Iterator        certIt = certCollection.iterator();
> >               X509Certificate certificado = (X509Certificate)
> > certIt.next();
> > 
> >               dumpSigner(signer);
> >                            System.out.println(" with cert ...\n " + 
> > certificado);
> >               if (signer.verify(certificado,"BC"))
> >                                System.out.println("Simple
> > verify verified something");
> >                        else System.out.println("verification
> > failed");
> > 
> >       }
> >                     checkContent2(docdata);
> > 
> >           //          getting the signature data as bytearray
> >           byte[] signeddata = s.getEncoded();
> >                ByteArrayInputStream bIn = new
> > ByteArrayInputStream(signeddata);
> >           ASN1InputStream      aIn = new ASN1InputStream
> > (bIn);
> >           DERObject aDERObject = aIn.readObject();
> >                              //        and then writing as 
> a DER-Stream
> >           ByteArrayOutputStream aOutStream = new
> > ByteArrayOutputStream();
> >           DEROutputStream aDEROutStream = new
> > DEROutputStream(aOutStream);
> >           aDEROutStream.writeObject(aDERObject);
> >           aOutStream.close();
> >           byte [] signedFixedLengthData =
> > aOutStream.toByteArray();                   byte [] 
> hexFixedLengthData 
> > = Hex.encode
> > (signedFixedLengthData);
> >                     int signedsize = s.getEncoded().length;
> >                System.out.println("Len: "+signedsize);
> >                signature.setContents(hexFixedLengthData);
> >                        PdfIndirectObject sdIndirect = 
> writer.addToBody
> > (signature);
> > 
> >            acroForm.addSignature("signature", 0, 0, 0, 0).put
> > (PdfName.V,sdIndirect.getIndirectReference());
> > 
> >            doc.close();
> > }
> > catch (Throwable tossed) { tossed.printStackTrace(); }
> > return true;
> > }
> > 
> > 
> > // I have extracted the contents of the signature object from a PDF
> > already signed with Acrobat.
> > // I try to verify it with the certificate .pfx file I used to sign
> > this document.
> > // This doesn�t work, it looks there's a problem with the algorithm
> > used to digest the message.
> > 
> > 
> > private boolean checkContent2(byte[] checkBytes) {
> >        String strDigest = CMSSignedDataGenerator.DIGEST_SHA1;
> >        byte[] contentbytes = new byte[0];
> >        Certificate[] certs = null;
> >        Collection certList = new ArrayList();
> >               try {
> >                RandomAccessFile raf = new RandomAccessFile
> > ("chkContent","r");
> > 
> >                byte[] docdata = new byte[(int)raf.length()];
> >                raf.readFully(docdata);
> >                raf.close();
> >                       byte[] bIs = codeSequence(docdata);
> >                                       CMSSignedData cmsdata = new 
> > CMSSignedData(bIs);
> >                       ByteArrayInputStream bin = new
> > ByteArrayInputStream(cmsdata.getEncoded());
> >                       ASN1InputStream aaIn = new 
> ASN1InputStream(bin);
> >                               CMSSignedData cmssigned = new 
> > CMSSignedData(new
> > CMSProcessableByteArray(checkBytes), ContentInfo.getInstance
> > (aaIn.readObject()));
> >                SignerInformationStore sinfo =
> > cmssigned.getSignerInfos();
> >                       CertStore cs = 
> cmssigned.getCertificatesAndCRLs
> > ("Collection","BC");
> >                Collection c = sinfo.getSigners();
> >                Object[] sia = c.toArray();
> >                Iterator it = c.iterator();
> >                while (it.hasNext()) {
> >                        SignerInformation signer =
> > (SignerInformation)it.next();
> >                        Collection ccollect = cs.getCertificates
> > (signer.getSID());
> >                        Iterator certit = ccollect.iterator();
> >                        X509Certificate cert = (X509Certificate)
> > certit.next();
> >                        dumpSigner(signer);
> >                        System.out.println(" \nwith cert ... "
> > + cert);
> >                        if (signer.verify(cert,"BC"))
> >                                System.out.println("Simple
> > verify verified something");
> >                        else System.out.println("verification
> > failed");
> >        }
> > 
> > }
> > catch (Throwable tossed) { tossed.printStackTrace(); }
> > return true;
> > }
> > 
> > public void dumpSigner(SignerInformation signer)
> > {
> >        System.out.println("Signer... " + signer);
> >        System.out.println("  DigestAlgoOID: 
> "+signer.getDigestAlgOID());
> >        System.out.println("  
> > DigestAlgoParams: "+signer.getDigestAlgParams());
> >        System.out.println("  
> > EncryptionAlgOID: "+signer.getEncryptionAlgOID());
> >        System.out.println("  
> > EncriptionAlgParams:   "+signer.getEncryptionAlgParams());
> >        }
> > 
> > public byte[] codeSequence(byte[] inBytes)
> > {
> >        byte[] result = new byte[inBytes.length/2];
> >               try {
> >                for (int i=0; i<inBytes.length/2; i++)
> >                {
> >                        result[i] = (byte)Integer.parseInt(new
> > String(inBytes, 2*i, 2),16);
> >                }
> >                       } catch (Exception ex) {
> >                ex.printStackTrace();
> >        }
> >               return result;
> >        }
> > 
> > private char[] storepswd =
> > {'f','i','l','e','p','a','s','s','w','o','r','d'};
> > private String alias;
> > 
> > }
> > 
> > Program dump ...
> > 
> > Signer... [EMAIL PROTECTED]
> > 
> > // Note the DigestAlgoID is SHA1 when I use the BC suite, :)
> > 
> > DigestAlgoOID: 1.3.14.3.2.26
> > DigestAlgoParams: [EMAIL PROTECTED]
> > EncryptionAlgOID: 1.2.840.113549.1.1.1
> > EncriptionAlgParams:   [EMAIL PROTECTED]
> > with cert ...
> >  [0]         Version: 3
> >        SerialNumber: 1069356515858876328712438690262151
> >            IssuerDN: CN=jose fernandez,O=company,OU=department,C=US
> >          Start Date: Thu Aug 26 12:19:32 CEST 2004
> >          Final Date: Wed Aug 26 12:19:32 CEST 2009
> >           SubjectDN: CN=jose fernandez,O=company,OU=department,C=US
> >          Public Key: RSA Public Key
> >           modulus:
> > 
> bf431f8fc58e17f222e82c8dd919ca48edae196b634f9b7291967c1affdde3
> 1056f78cc8
> > 
> dd54bec15185cc4171b8fcd21e5edccf8fa78d2808a1dff7dffc3dbe5871ee
> 3e1eca34e4
> > 
> 05f776bbbe27a99d94cdd410c2efcab801a948eac12cbf8216ec034a62a389
> 58aae4b4aa
> > 178d8d06dfd181756b04af0253582d3078e42a3d
> >   public exponent: 10001
> > 
> > Signature Algorithm: SHA1WithRSAEncryption
> >           Signature: 18c2db4752e6b998247b5578e7ff50d8140d0360
> >                      a90ac40ef256faee1b48e74ffc960212dc25c689
> >                      2115ef33b7475548d618b54b6d566c54e8aa1a7b
> >                      09282a07e8666154913ece270876fa828de2092c
> >                      fb47fccbbc5ef1302f2d98aad2a9454eee588593
> >                      e0089e534fdd04a66cc76130c0dab9bc198ea6fc
> >                      959530dd8cbd14ad
> >      Extensions:
> >                      critical(false) KeyUsage: 0x90
> > 
> > Simple verify verified something
> > Signer... [EMAIL PROTECTED]
> > 
> > // The DigestAlgoID used by Adobe is RSAwithSHA1, :(
> > // Is it possible to manage this algorithm with the BC suite ?
> > 
> > DigestAlgoOID: 1.2.840.113549.1.1.5
> > DigestAlgoParams: [EMAIL PROTECTED]
> > EncryptionAlgOID: 1.2.840.113549.1.1.1
> > EncriptionAlgParams:   [EMAIL PROTECTED]
> > 
> > with cert ...   [0]         Version: 3
> >        SerialNumber: 1069356515858876328712438690262151
> >            IssuerDN: CN=jose fernandez,O=company,OU=department,C=US
> >          Start Date: Thu Aug 26 12:19:32 CEST 2004
> >          Final Date: Wed Aug 26 12:19:32 CEST 2009
> >           SubjectDN: CN=jose fernandez,O=company,OU=department,C=US
> >          Public Key: RSA Public Key
> >           modulus:
> > 
> bf431f8fc58e17f222e82c8dd919ca48edae196b634f9b7291967c1affdde3
> 1056f78cc8
> > 
> dd54bec15185cc4171b8fcd21e5edccf8fa78d2808a1dff7dffc3dbe5871ee
> 3e1eca34e4
> > 
> 05f776bbbe27a99d94cdd410c2efcab801a948eac12cbf8216ec034a62a389
> 58aae4b4aa
> > 178d8d06dfd181756b04af0253582d3078e42a3d
> >   public exponent: 10001
> > 
> > Signature Algorithm: SHA1WithRSAEncryption
> >           Signature: 18c2db4752e6b998247b5578e7ff50d8140d0360
> >                      a90ac40ef256faee1b48e74ffc960212dc25c689
> >                      2115ef33b7475548d618b54b6d566c54e8aa1a7b
> >                      09282a07e8666154913ece270876fa828de2092c
> >                      fb47fccbbc5ef1302f2d98aad2a9454eee588593
> >                      e0089e534fdd04a66cc76130c0dab9bc198ea6fc
> >                      959530dd8cbd14ad
> >      Extensions:
> >                      critical(false) KeyUsage: 0x90
> > 
> > Len: 978
> > 
> > 
> > // ..............
> > 
> > 
> > And I receive the following exception:
> > 
> > java.security.NoSuchAlgorithmException: no such algorithm: 
> > 1.2.840.113549.1.1.5withRSA for provider BC
> >  at java.security.Security.getEngineClassName(Security.java:635)
> >  at java.security.Security.getEngineClassName(Security.java:605)
> >  at java.security.Security.getImpl(Security.java:1044)
> >  at java.security.Signature.getInstance(Signature.java:218)
> >  at org.bouncycastle.cms.SignerInformation.verify
> > (SignerInformation.java:397)
> >  at SignProblem.checkContent2(SignProblem.java: 274)
> >  at SignProblem.init(SignProblem.java:201)
> >  at SignProblem.main(SignProblem.java:79)
> > 
> > 
> > I would appreciate very much any kind of help about how to insert a
> > digital signature into a pdf file, with the BC suite.
> > Is it possible?
> > 
> > Thank you, very much in advance.
> > Cheers,
> > juan
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> 
> 
> -- 
> Try this useful extra toolbar for your browser:
> http://download.alexa.com/?amzn_id=itisacatalofwebp
> 
> 
> -------------------------------------------------------
> This SF.Net email is sponsored by BEA Weblogic Workshop
> FREE Java Enterprise J2EE developer tools!
> Get your free copy of BEA WebLogic Workshop 8.1 today.
> http://ads.osdn.com/?ad_id=5047&alloc_id=10808&op=click
> _______________________________________________
> iText-questions mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/itext-questions
> 


-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_idP47&alloc_id808&op=click
_______________________________________________
iText-questions mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/itext-questions

Reply via email to