PAdES (PDF Advanced Electronic Signatures) is a set of restrictions and extensions to PDF and ISO 32000-1 making it suitable for Advanced Electronic Signature. This is published by ETSI as TS 102 778.

While PDF and ISO 32000-1 provide a framework for digitally signing their documents, PAdES specifies precise profiles making it compliant with the European eIDAS regulation (Regulation on electronic identification and trust services for electronic transactions in the internal market). The eIDAS regulation enhances and repeals the Electronic Signatures Directive 1999/93/EC. EIDAS is legally binding in all EU member states since July 2014. An electronic signature that has been created in compliance with eIDAS has the same legal value as a handwritten signature.

An electronic signature, technically implemented based on PAdES has the status of an advanced electronic signature. This means that

  • it is uniquely linked to the signatory;
  • it is capable of identifying the signatory;
  • only the signatory has control of the data used for the signature creation;
  • it can be identified if data attached to the signature has been changed after signing.

One important benefit from PAdES is that electronically signed documents can remain valid for long periods, even if underlying cryptographic algorithms are broken.

PAdES recognizes that digitally-signed documents may be used or archived for many years – even many decades. At any time in the future, in spite of technological and other advances, it must be possible to validate the document to confirm that the signature was valid at the time it was signed – a concept known as Long-Term Validation (LTV).

The PAdES standard, ETSI Technical Specification (TS) 102 778, introduces a number of adaptations and extensions to PDF to satisfy the Directive's requirements. ETSI will feed these European-specific elements back into ISO for inclusion in the next release of the PDF standard, ISO 32000-2.

The PAdES standard (ETSI TS 102 778) profiles support for PDF 1.7 format (ISO 32000-1) digital signatures for including advanced digital signatures in PDF documents. It also extends this support as it defines additional data structures for maintaining signature validity over time. It is planned for the ISO 32000-1 extensions defined by PAdES to be included in ISO 32000-2.

Specifically, PAdES (ETSI TS 102 778) defines the following profiles:

  • PAdES-CMS: This profile defines a CMS/PKCS#7 digital signature based on ISO 32000-1, which requires that the /ByteRange key of the digital signature dictionary covers the entire file and that the /subFilter key only contains the values adbe.pkcs7.detached and adbe.pkcs7.sha1. In addition, this profile recommends including a time-stamp as an unsigned attribute of the CMS/PKCS#7. The TrustedX digital signature services currently support signing PDF documents using this PAdES profile.
  • PAdES-BES and PAdES-EPES: This profile defines CAdES-BES (ETSI TS 101 733) and CAdES-EPES (ETSI TS 101 733) digital signatures that require that the /ByteRange key of the digital signature dictionary covers the entire document and that the /subFilter key contains the value ETSI.CAdES.detached. Use of the/Cert key is prohibited. Both digital signature types allow including a time-stamp, which would, in fact, make them CAdES-T (ETSI TS 101 733) digital signatures. So, the PAdES-BES and PAdES-EPES digital signatures have the same characteristics as the CAdES-BES, CAdES-EPES and CAdES-T digital signatures. The TrustedX digital signature generation service currently supports signing PDF documents using this PAdES profile.
  • PAdES-LTV: This profile constitutes an extension of ISO 32000-1 as it defines two structures that support extending digital signature validity for any length of time. On the one hand, it defines the DSS (Document Security Store) dictionary for storing all the validation data (CA certificates, CRLs and OCSP responses) required to validate the document digital signatures, and on the other, it defines the Document Time-stamp dictionary, which is an ISO 32000-1 digital signature dictionary whose /subFilter key has the value ETSI.RFC.3161 and which contains a time-stamp for the entire PDF document, including the DSS dictionary containing all the validation data for the signatures. This time-stamp maintains, while it is valid, the proof value for the validation data of the digital signatures. I.e., it maintains their strength beyond their expiry date. Furthermore, before the first time-stamp expires, the DSS and Document Time-stamp structures can be reused to maintain the proof value of this stamp and so maintain the digital signature's validity. In this case, the DSS dictionary contains the validation data of the first time-stamp, and the Document Time-stamp dictionary contains a second time-stamp that, again, covers the entire document. Thus, by repeating the addition of a DSS dictionary that contains the validation data of the last time-stamp and the addition of the Document Time-stamp dictionary, the validity of digital signatures in PDF documents can be maintained for any length of time. By using the PAdES-LTV profile on the PDF documents that contain the digital signatures generated as per the PAdES-BES and PAdES-EPES profiles, digital signatures with the same long-term characteristics as the CAdES-XL and CAdES-A (ETSI TS 101 733) are obtained. The TrustedX digital signature generation service currently supports updating PDF documents using this PAdES-LTV profile.
  • PAdES-XML: This profile comprises a set of profiles that describe how to use the XAdES (ETSI 101 903) digital signatures in PDF documents. Specifically, a distinction is made between any XML documents signed as per XAdES and XFA forms signed as per XAdES.

1 Enum constants

For either signature level, signature packaging and digest algorithm and enum constant is provided.

Copy
<script>
    console.log(Ax.crypt.PAdES.SIGNATURELEVEL);
    console.log(Ax.crypt.PAdES.DIGESTALGORITHM);
</script>
[PAdES_BASELINE_B, PAdES_BASELINE_LT, PAdES_BASELINE_LTA, PAdES_BASELINE_T]
[SHA256, SHA3_384, SHA1, SHA384, RIPEMD160, SHA3_512, MD2, SHA3_224, SHA3_256, SHA512, SHA224, MD5]

2 Signature example

Sign a PDF document without any text layer or image.

Copy
<script>

    var ksStream = new Ax.net.URL('https://bitbucket.org/deister/axional-docs-resources/raw/master/KeyStores/swview/jks-files/jack.jks');

    // Load a keystore
    var ks = new Ax.ks.KeyStoreManager(ksStream.getInputStream(), "secret");
    
    // Load a PDF document
    var src = new Ax.net.URL('https://bitbucket.org/deister/axional-docs-resources/raw/master/PDF/sample.pdf');
    
    // Sign the document using keystore private key alias "jack" with password "moon"
    var tmp = new Ax.crypt.PAdES(src)
    	.setTspServer("http://tsa.belgium.be/connect")
    	.setSignatureLevel(Ax.crypt.PAdES.SIGNATURELEVEL.PAdES_BASELINE_T)
     	.setReason("The reason I sign")
     	.setContactInfo("The contact information")
     	.setSignatureName("The signature name")
    	.sign(ks, "jack", "moon")
    ;
    
    new Ax.io.File("/tmp/pades1.pdf").write(tmp);
    console.log(tmp);   
</script>

3 Signature with image

Sign a document and place an image icon at first page. Image is provided as Bas64 encoded string.

Copy
<script>
    // Load a keystore
    var ks = new Ax.ks.KeyStoreManager ("https://bitbucket.org/deister/axional-docs-resources/raw/master/KeyStores/swview/jks-files/jack.jks", "secret");
    
    // Load a PDF document
    var src = new Ax.net.URL('https://bitbucket.org/deister/axional-docs-resources/raw/master/PDF/sample.pdf');
    
    // Sign the document using keystore private key alias "jack" with password "moon"
    var tmp = new Ax.crypt.PAdES(src)
    	.setTspServer("http://tsa.belgium.be/connect")
    	.setSignatureLevel(Ax.crypt.PAdES.SIGNATURELEVEL.PAdES_BASELINE_T)
     	.setReason("The reason I sign")
     	.setContactInfo("The contact information")
     	.setSignatureName("The signature name")
     	.setSignatureImageParameters(options => {
       	   options.setPage(1);
           options.setxAxis(20);
      	   options.setyAxis(20);
      	   //options.setWidth(100);
      	   //options.setHeight(100);
      	   //options.setRotation(180);
    	   options.setImage(Ax.util.Base64.decode('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'));
     	})
    	.sign(ks, "jack", "moon")
    ;
    
    new Ax.io.File("/tmp/pades2.pdf").write(tmp);
</script>

4 Signature with text only

Sign a document and place an image text at first page.

Copy
<script>
    // Load a keystore
    var ks = new Ax.ks.KeyStoreManager("https://bitbucket.org/deister/axional-docs-resources/raw/master/KeyStores/swview/jks-files/jack.jks", "secret");
    
    // Load a PDF document
    var src = new Ax.net.URL('https://bitbucket.org/deister/axional-docs-resources/raw/master/PDF/sample.pdf');
    
   // Sign the document using keystore private key alias "jack" with password "moon"
    var tmp = new Ax.crypt.PAdES(src)
    	.setTspServer("http://tsa.belgium.be/connect")
    	.setSignatureLevel(Ax.crypt.PAdES.SIGNATURELEVEL.PAdES_BASELINE_T)
     	.setReason("The reason I sign")
     	.setContactInfo("The contact information")
     	.setSignatureName("The signature name")
     	.setSignatureImageParameters(options => {
       	   options.setPage(1);
           options.setxAxis(20);
      	   options.setyAxis(20);
      	   options.setText("The signatue text");
      	   options.setTextColor(255, 255, 0);
      	   options.setBackgroundColor(255, 0, 0);
      	   options.setSignerNamePosition("TOP");
      	   options.setSignerTextHorizontalAlignment("LEFT");
     	})
    	.sign(ks, "jack", "moon")
    ;
 
    new Ax.io.File("/tmp/pades3.pdf").write(tmp);
</script>