Great! The problema was
doc.save(...) Now the PDF is certified. I would like to be LTV also. What are the things that make a signature LTV ? Thank you Damien and Diego! On Wed, Oct 19, 2016 at 6:09 PM, Damien Butaye <damien.but...@gmail.com> wrote: > Hello Jonathan, > > Try also to use doc.saveIncremental(out) instead of doc.save(out) > > Le 19 oct. 2016 23:01, "Diego Azevedo" <dazev...@esec.com.br> a écrit : > >> Hello Jonathan, >> >> After 'dictionary.setItem("Reference", references);' line, add: >> >> //Create Permissions Dictionary >> COSDictionary permissions = new COSDictionary(); >> permissions.setItem("DocMDP", signature); >> >> //Add Permissions to Catalog >> COSDictionary catalog = document.getDocumentCatalog().getCOSObject(); >> catalog.setItem("Perms", permissions); >> >> It is expected to see a difference in Contents and byteRange using >> different libraries, since they may or may not use references, spaces or >> line breaks the same way. >> []'s >> >> Diego Azevedo >> >> On 19/10/2016 17:09, Jonathan Barbero wrote: >> >> Hi, >> >> I have tried to certify a PDF with the provided code, but failed. This >> is the code I'm trying >> >> >> >> final PrivateKey privateKey = ... >> final Certificate certificate = ... >> >> >> >> PDDocument doc = PDDocument.load(input); >> >> // PDSignature >> PDSignature signature = new PDSignature(); >> >> signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); >> signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED); >> signature.setReason("The reason"); >> signature.setName("The name"); >> signature.setSignDate(Calendar.getInstance()); >> >> // DocMDP thing >> >> COSDictionary dictionary = signature.getCOSObject(); >> >> //Create Permissions Dictionary >> COSDictionary permissions = new COSDictionary(); >> permissions.setItem("DocMDP", signature); >> //Add Permissions to Catalog >> COSDictionary catalog = doc.getDocumentCatalog().getCOSObject(); >> catalog.setItem("Perms", permissions); >> // Create a reference dictionary >> COSDictionary reference = new COSDictionary(); >> reference.setItem("Type", COSName.getPDFName("SigRef")); >> reference.setItem("TransformMethod", COSName.getPDFName("DocMDP")); >> reference.setItem("DigestMethod", COSName.getPDFName("SHA1")); >> // Now we add DocMDP specific stuff >> COSDictionary transformParameters = new COSDictionary(); >> transformParameters.setItem("Type", COSName.getPDFName("TransformP >> arams")); >> transformParameters.setInt("P", 2); // >> >> transformParameters.setItem("V", COSName.getPDFName("1.2")); >> >> >> // Add everything in order >> reference.setItem("TransformParams", transformParameters); >> >> >> COSArray references = new COSArray(); >> references.add(reference); // Add SigRef Dictionary to a Array >> >> dictionary.setItem("Reference", references); // Add Array to Signature >> // dictionary >> >> >> >> // From CreateSignature.java example >> // register signature dictionary and sign interface >> doc.addSignature(signature, new SignatureInterface() { >> @Override >> public byte[] sign(InputStream content) throws IOException { >> try { >> List<Certificate> certList = new ArrayList<Certificate>(); >> certList.add(certificate); >> Store certs = new JcaCertStore(certList); >> CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); >> org.bouncycastle.asn1.x509.Certificate cert = >> org.bouncycastle.asn1.x509.Certificate >> .getInstance(ASN1Primitive.fromByteArray(certificate.getEncoded())); >> ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA25 >> 6WithRSA").build(privateKey); >> gen.addSignerInfoGenerator( >> new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBui >> lder().build()) >> .build(sha1Signer, new X509CertificateHolder(cert))); >> gen.addCertificates(certs); >> CMSProcessableInputStream msg = new CMSProcessableInputStream(content); >> CMSSignedData signedData = gen.generate(msg, false); >> /* >> * if (tsaClient != null) { signedData = >> * signTimeStamps(signedData); } >> */ >> return signedData.getEncoded(); >> } catch (GeneralSecurityException e) { >> throw new IOException(e); >> } catch (CMSException e) { >> throw new IOException(e); >> // } catch (TSPException e) { >> // throw new IOException(e); >> } catch (OperatorCreationException e) { >> throw new IOException(e); >> } >> } >> }); >> >> // >> doc.save(output); >> >> doc.close(); >> >> >> When I open the PDF in Acrobat >> >> >> [image: Inline image 1] >> >> I compared a PDF certified with a paid library and the one generated with >> my code. There is a difference in *contents, *and the *byte ranges* are >> wrong. >> >> Left paid library, right the code example >> [image: Inline image 2] >> >> >> The SignatureInterface implementation is the one from >> CreateSignature.java example. >> >> >> Thanks in advance, >> >> Jonathan. >> >> On Wed, Oct 19, 2016 at 11:03 AM, Damien Butaye <damien.but...@gmail.com> >> wrote: >> >>> Diego, >>> >>> One more times, thanks a lot. I just add the following part of your code >>> and it works! : >>> >>> >>> >>> >>> >>> >>> >>> >>> * //Create Permissions Dictionary COSDictionary permissions = >>> new COSDictionary(); permissions.setItem("DocMDP", signature); >>> //Add Permissions to Catalog COSDictionary catalog = >>> document.getDocumentCatalog().getCOSObject(); >>> catalog.setItem("Perms", permissions);* >>> >>> Many Thanks! >>> Damien. >>> >>> 2016-10-19 15:43 GMT+02:00 Diego Azevedo <dazev...@esec.com.br>: >>> >>> > Ok, I searched for "DocMDP" on ISO 32000 and found this: >>> > >>> > * On a 'Signature Field Dictionary', one *could *have a 'Seed Value >>> > Dictionary' with a 'MDP entry' >>> > o This entry *shall *have a dictionary with only one entry: 'P' >>> > and a integer value <0-3>: >>> > + 0 - Author Signature >>> > + 1-3 - Same meaning from the P entry on the DocMDP Transform >>> > Parameters Dictionary >>> > * A certification Signature *may *be referenced from the DocMDP entry >>> > in the Permissions Dictionary >>> > o The signature Dictionary *shall *contain a signature reference >>> > dictionary with the DocMDP transform method >>> > o It *should *have a Legal Attestation Dictionary >>> > o It *shall *be the first signed field in the document >>> > >>> > There where a few specific things about these entries and dictionaries, >>> > but these are the changes that should be made from the beginning: >>> > >>> > * Create the Signature Reference Dictionary and add it to the >>> > signature - OK >>> > * Create a Permissions Dictionary and add it to Catalog: >>> > >>> > //Create Permissions Dictionary >>> > COSDictionary permissions = new COSDictionary(); >>> > permissions.setItem("DocMDP", signature); >>> > >>> > //Add Permissions to Catalog >>> > COSDictionary catalog = >>> > document.getDocumentCatalog().getCOSObject(); >>> > catalog.setItem("Perms", permissions); >>> > >>> > * Create a Legal Attestation Dictionary and add it to catalog: >>> > >>> > //Create Legal Attestation Dictionary (I'd totally leave this >>> > out on my implementation - Way too much trouble for something >>> > optional) >>> > COSDictionary legalAttestation= new COSDictionary(); >>> > <All entries are optional, and are like this:> >>> > legalAttestation.setInt("JavaScriptActions", 10);// Means there >>> > are 10 Javascript actions >>> > legalAttestation.setInt("LaunchActions", 10);// Means there are >>> > 10 Launch actions >>> > [...] >>> > >>> > //Add Permissions to Catalog >>> > COSDictionary catalog = >>> > document.getDocumentCatalog().getCOSObject(); >>> > catalog.setItem("Legal", legalAttestation); >>> > >>> > * Create a Seed Value Dictionary and add it to the Signature Field >>> > Dictionary >>> > o The Signature Field Dictionary is manipulated by pdfbox itself >>> > on document.addSignature. So, if necessary, it would be >>> > something like this that would be changed in the source code: >>> > >>> > //Get the references >>> > COSArray references = (COSArray) >>> > signature.getCOSObject().getItem("Reference"); >>> > COSDictionary reference = null; >>> > if( references != null){ >>> > >>> > // loop all references, looking for a DocMDP TransformMethod >>> > for(int i = 0; i< references.size(); i++){ >>> > >>> > reference = (COSDictionary) references.getObject(i); >>> > if(reference.getNameAsString(" >>> TransformMethod").equals("Doc >>> > MDP")){ >>> > >>> > // if it is a DocMDP, it shall heve TransformParams >>> > as a integer >>> > COSDictionary transform = (COSDictionary) >>> > reference.getItem("TransformParams"); >>> > int pEntry = transform.getInt("P"); >>> > >>> > //Add to the SeedValue Dictionary >>> > PDSeedValue seedValue = ?; //How to get the >>> > SeedValue? Should we create a new one? - Only >>> > someone from the project could tell you that (along >>> > with where this code should be placed) >>> > PDSeedValueMDP mdp = new PDSeedValueMDP(); >>> > mdp.setP(pEntry); >>> > seedValue.setMPD(mdp); >>> > >>> > } >>> > >>> > } >>> > >>> > } >>> > >>> > I only saw your reply now. The document you sent me only did the first >>> > change (permissions Dictionary). Try it and tell me if it worked >>> > >>> > []'s >>> > >>> > Diego Azevedo >>> > >>> > >>> > On 19/10/2016 09:25, Diego Azevedo wrote: >>> > >>> >> Damien, >>> >> >>> >> Can you upload a correctly certified PDF somewhere and share the link? >>> >> Wîth the original one, if possible? >>> >> >>> >> I'll try to mimic the behavior. >>> >> >>> >> []'s >>> >> >>> >> Diego Azevedo >>> >> >>> >> On 19/10/2016 07:10, Damien Butaye wrote: >>> >> >>> >>> In some Java code of different PDF Signatue framework, I saw the use >>> of >>> >>> the >>> >>> "Perms" dictionnary to certify PDF. Do you have any idea if the >>> "Perms" >>> >>> can >>> >>> help to see the blue ribbon? >>> >>> >>> >>> 2016-10-19 10:48 GMT+02:00 Damien Butaye <damien.but...@gmail.com>: >>> >>> >>> >>> Yes but in my case my certificate has the authorization to certify >>> >>>> document (the cross is green beside the "Certify Document" in your >>> >>>> previous >>> >>>> printscreen). >>> >>>> I wonder me if another information must be present in the PDF to >>> show >>> >>>> the >>> >>>> blue ribbon?! >>> >>>> >>> >>>> 2016-10-18 17:40 GMT+02:00 Diego Azevedo <dazev...@esec.com.br>: >>> >>>> >>> >>>> No, but in my case it would never happen, because my certificate is >>> >>>>> trusted for signing, but not certifying: >>> >>>>> >>> >>>>> Image: http://imgur.com/XYZCB8H >>> >>>>> >>> >>>>> []'s >>> >>>>> >>> >>>>> Diego Azevedo >>> >>>>> >>> >>>>> On 18/10/2016 13:30, Damien Butaye wrote: >>> >>>>> >>> >>>>> One last question, have you got the "blue ribbon" on the top the >>> pdf >>> >>>>>> when you open it with Acrobat? In my case not, although it is well >>> >>>>>> certified as shown in the Acrobat Signature Panel. >>> >>>>>> >>> >>>>>> >>> >>>>>> >>> >>>>>> 2016-10-18 15:58 GMT+02:00 Damien Butaye <damien.but...@gmail.com >>> >>>>>> <mailto:damien.but...@gmail.com>>: >>> >>>>>> >>> >>>>>> Nice! Thank you very much! >>> >>>>>> >>> >>>>>> (Btw, it could be nice to integrate in a future release a >>> method >>> >>>>>> certify() in the PDSignature object). >>> >>>>>> >>> >>>>>> obrigado! >>> >>>>>> >>> >>>>>> 2016-10-18 15:42 GMT+02:00 Diego Azevedo < >>> dazev...@esec.com.br >>> >>>>>> <mailto:dazev...@esec.com.br>>: >>> >>>>>> >>> >>>>>> Hello Damien, >>> >>>>>> >>> >>>>>> I made a typo: >>> >>>>>> >>> >>>>>> dictionary.setItem("Reference", reference_*s*_); // >>> Add >>> >>>>>> Array to Signature dictionary >>> >>>>>> >>> >>>>>> There is no point in creating the array, add the "SigRef" >>> >>>>>> dictionary to it... and not use the array on the "Sig" >>> >>>>>> dictionary. So... just add the 'S' to the variable and >>> >>>>>> re-run >>> >>>>>> it. Just tested here, and it worked fine =) >>> >>>>>> >>> >>>>>> []'s >>> >>>>>> >>> >>>>>> >>> >>>>>> -- *_______________________________________________ >>> >>>>>> >>> >>>>>> Diego Azevedo >>> >>>>>> Developer >>> >>>>>> E-SEC Segurança Digital >>> >>>>>> www.esec.com.br <http://www.esec.com.br> >>> >>>>>> +55 61 3323-4410 <tel:%2B55%2061%203323-4410> >>> <%2B55%2061%203323-4410>* >>> >>>>>> >>> >>>>>> >>> >>>>>> On 18/10/2016 10:21, Damien Butaye wrote: >>> >>>>>> >>> >>>>>> Hello Diego, >>> >>>>>>> >>> >>>>>>> Thank you for your help. I just tried your code but it >>> >>>>>>> seems >>> >>>>>>> that it doesn't work. The result has nor signature nor >>> >>>>>>> certify element. I'll try again. >>> >>>>>>> If you have any idea, don't hesitate ;) >>> >>>>>>> >>> >>>>>>> Damien. >>> >>>>>>> >>> >>>>>>> 2016-10-18 13:04 GMT+02:00 Diego Azevedo >>> >>>>>>> <dazev...@esec.com.br <mailto:dazev...@esec.com.br>>: >>> >>>>>>> >>> >>>>>>> >>> >>>>>>> From what I'm reading on ISO 32000, the >>> certification >>> >>>>>>> Signature is a normal signature, but with a DocMDP >>> >>>>>>> transform method. So the ou should do something like >>> >>>>>>> this: >>> >>>>>>> >>> >>>>>>> PDSignature signature = new PDSignature; >>> >>>>>>> [..] //do your thing >>> >>>>>>> COSDictinary dictionary = >>> signature.getCOSObject(); >>> >>>>>>> >>> >>>>>>> //Create a reference dictionary >>> >>>>>>> COSDictionary reference = new COSDictionary(); >>> >>>>>>> reference.setItem("Type", >>> >>>>>>> COSName.getPDFName("SigRef")); >>> >>>>>>> reference.setItem("TransformMethod", >>> >>>>>>> COSName.getPDFName("DocMDP")); >>> >>>>>>> reference.setItem("DigestMethod", >>> >>>>>>> COSName.getPDFName("SHA1")); //Only MD5 or >>> SHA1... >>> >>>>>>> Go >>> >>>>>>> with the least worse >>> >>>>>>> >>> >>>>>>> //Now we add DocMDP specific stuff >>> >>>>>>> COSDictionary transformParameters = new >>> >>>>>>> COSDictionary(); >>> >>>>>>> transformParameters.setItem("Type", >>> >>>>>>> COSName.getPDFName("TransformParams")); >>> >>>>>>> transformParameters.setInteger("P", <1, 2 or >>> 3>); >>> >>>>>>> // >>> >>>>>>> 1- no changes permited; 2- fill forms and >>> signing; >>> >>>>>>> 3- >>> >>>>>>> Same as 2 plus annotation creation, deletion an >>> >>>>>>> modification. >>> >>>>>>> transformParameters.setItem("V", >>> >>>>>>> COSName.getPDFName("1.2")); // This is right, >>> it's a >>> >>>>>>> name, not a number. >>> >>>>>>> >>> >>>>>>> // Add everything in order >>> >>>>>>> reference.setItem("TransformParams", >>> >>>>>>> transformParameters ); // Add DocMDP stuff to >>> the >>> >>>>>>> SigRef Dictionary; >>> >>>>>>> COSArray references = new COSArray(); >>> >>>>>>> references.add(reference); // Add SigRef >>> Dictionary >>> >>>>>>> to a Array >>> >>>>>>> dictionary.setItem("Reference", reference); // >>> Add >>> >>>>>>> Array to Signature dictionary >>> >>>>>>> >>> >>>>>>> I didn't try it myself, just wrote based on PdfBox >>> API >>> >>>>>>> and ISO specification. May have errors. >>> >>>>>>> >>> >>>>>>> On 18/10/2016 06:12, Damien Butaye wrote: >>> >>>>>>> >>> >>>>>>> Hello Tilman, >>> >>>>>>>> >>> >>>>>>>> Here follows two links explaining the difference >>> : >>> >>>>>>>> >>> >>>>>>>> >>> >>>>>>>> 1.http://www.investintech.com/ >>> >>>>>>>> resources/articles/certifyingsigningpdf/ >>> >>>>>>>> <http://www.investintech.com/r >>> >>>>>>>> esources/articles/certifyingsigningpdf/> >>> >>>>>>>> 2. >>> >>>>>>>> http://stackoverflow.com/quest >>> >>>>>>>> ions/16710439/how-to-add-blank-page-in-digitally-signed-pdf- >>> >>>>>>>> using-java/16711745#16711745 >>> >>>>>>>> <http://stackoverflow.com/ques >>> >>>>>>>> tions/16710439/how-to-add-blank-page-in-digitally-signed-pdf >>> >>>>>>>> -using-java/16711745#16711745>Damien. >>> >>>>>>>> 2016-10-18 8:49 GMT+02:00 Tilman Hausherr >>> >>>>>>>> <thaush...@t-online.de> <mailto: >>> thaush...@t-online.de> >>> >>>>>>>> : >>> >>>>>>>> >>> >>>>>>>> Dear all, >>> >>>>>>>>> >>> >>>>>>>>> I'm looking for a solution to certify a PDF. >>> >>>>>>>>>> Currently I'm able to >>> >>>>>>>>>> sign a >>> >>>>>>>>>> PDF using PDFBox but I can't certify it. Is-it >>> >>>>>>>>>> possible >>> >>>>>>>>>> to do it with >>> >>>>>>>>>> PDFBox? >>> >>>>>>>>>> >>> >>>>>>>>>> >>> >>>>>>>>>> Thank you for your help! >>> >>>>>>>>>> >>> >>>>>>>>>> What's the difference? (See my other answer from >>> >>>>>>>>>> today) >>> >>>>>>>>>> >>> >>>>>>>>> Tilman >>> >>>>>>>>> >>> >>>>>>>>> >>> >>>>>>>>> >>> >>>>>>>>> ------------------------------ >>> >>>>>>>>> --------------------------------------- >>> >>>>>>>>> To unsubscribe, e-mail:users-unsubscribe@pdfbo >>> >>>>>>>>> x.apache.org >>> >>>>>>>>> <mailto:users-unsubscr...@pdfbox.apache.org> >>> >>>>>>>>> For additional commands, >>> >>>>>>>>> e-mail:users-help@pdfbox.apach >>> >>>>>>>>> e.org >>> >>>>>>>>> <mailto:users-h...@pdfbox.apache.org> >>> >>>>>>>>> >>> >>>>>>>>> >>> >>>>>>>>> >>> >>>>>>>>> >>> >> >>> >> >> >> -- >> >> >> >> >> >> >> *_______________________________________________ Diego Azevedo >> Desenvolvedor E-SEC Segurança Digital www.esec.com.br >> <http://www.esec.com.br> 61 3323-4410* >> >> >> Os dados transmitidos, incluindo quaisquer anexos, são destinados apenas >> para a pessoa ou entidade ao qual está endereçada e pode conter material >> confidencial e/ou privilegiado. É proibida qualquer revisão, retransmissão, >> disseminação ou outro uso desta informação, ou a tomada de qualquer ação >> com base na confiança, por pessoas ou empresas que não o destinatário, e >> qualquer responsabilidade daí decorrente é negada. Se você recebeu por >> engano, favor contatar o remetente e apague o material de qualquer >> computador >> >> The information transmitted, including any attachments, is intended only >> for the person or entity to which it is addressed and may contain >> confidential and/or privileged material. Any review, retransmission, >> dissemination or other use of, or taking of any action in reliance upon, >> this information by persons or entities other than the intended recipient >> is prohibited, and all liability arising therefrom is disclaimed. If you >> received this in error, please contact the sender and delete the material >> from any computer >> >>