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
