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("TransformParams"));
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("SHA256WithRSA").build(privateKey);
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().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


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
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 <[email protected] <mailto:[email protected]>> 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 <[email protected]
    <mailto:[email protected]>>:

    > 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
    <[email protected] <mailto:[email protected]>>:
    >>>
    >>> 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
    <[email protected] <mailto:[email protected]>>:
    >>>>
    >>>> 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
    <[email protected] <mailto:[email protected]>
    >>>>>> <mailto:[email protected]
    <mailto:[email protected]>>>:
    >>>>>>
    >>>>>>      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
    <[email protected] <mailto:[email protected]>
    >>>>>>      <mailto:[email protected]
    <mailto:[email protected]>>>:
    >>>>>>
    >>>>>>          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>
    <http://www.esec.com.br>
    >>>>>>          +55 61 3323-4410 <tel:%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
    >>>>>>>          <[email protected]
    <mailto:[email protected]> <mailto:[email protected]
    <mailto:[email protected]>>>:
    >>>>>>>
    >>>>>>>
    >>>>>>>              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
    >>>>>>>>              <[email protected]
    <mailto:[email protected]>> <mailto:[email protected]
    <mailto:[email protected]>>
    >>>>>>>> :
    >>>>>>>>
    >>>>>>>>              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 <http://x.apache.org>
    >>>>>>>>> <mailto:[email protected]
    <mailto:[email protected]>>
    >>>>>>>>>              For additional commands,
    >>>>>>>>> e-mail:[email protected]
    >>>>>>>>> e.org <http://e.org>
    >>>>>>>>> <mailto:[email protected]
    <mailto:[email protected]>>
    >>>>>>>>>
    >>>>>>>>>
    >>>>>>>>>
    >>>>>>>>>
    >>



--
*_______________________________________________

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

Reply via email to