PKI And Digital Signature. Part II: Digital Signature as a Service

Background

In the last post we talked about PKI and the service of Digital Identity founded on a new concept based on a combination of vetting, certificates, keys, Authorization Server and secure practices that allowed us to maintain successfully a community of users free from hacking by impersonation techniques.
In this post we are going to talk about a meaningful service that can be possible ONLY if you have available this Identity Management system first: Secure Digital Signature.

What is Digital Signature?

Obviously, you'll need some background to understand what a Digital Signature is.


Basically, you (Alice) have a document. You can sign the document (using certain tools, that's the question) that basically means you has to:
  • Calculate a hash from the content (bytes) of the document (we assume it is an electronic document, e.g. a PDF file) by using some algorithm (you can find a good article here).
  • Encrypt the hash with your private key. To do this properly, we have to assume you have a valid X509 certificate (please read our last post if you have any question in this subject). This information is included along with the old content of the document, that has been modified.
  • Then, send the document to Bob. He can verify that Alice was the author of the document by decrypting the encrypted hash with Alice's Public Key (which is publicly available).

We can add some complications to this really simple scenario:
  • There are several signatories.
  • They want to see their signatures onto the document even when the document is printed.
  • You want to lock the document to new signatures.
  • We want to verify that the document and the signatures contained are valid, they are not broken because the document content changed AFTER some signature was applied.
  • The documents have to be audited and reviewed, with immutable recording of all actions to support the signatures on documents because the legal validity of the documents can be challenged on court.

Real life scenarios make things more complicated, as you can see, and that's why a professional systems comes on our help.

 

eIDAS and Other Regulations



The EU released the eIDAS regulation as one of the most advanced attempts to regulate and ensure the quality and security in Digital Signature operations in the EU territory. It is a true big start and a signal of maturity for Digital Signatures in the European economy and European relationships. It distinguishes between three types of digital signatures considering the authority level that issues the digital identities (e.g. a X509 certificate, but not only).

Types of signatures in eIDAS

If we strictly look at the Regulation (EU) No 910/2014 (eIDAS), the three types of electronic signatures are defined as:

Simple or Basic electronic signature (SES). All electronic types of signatures that proves acceptance or approval by the signer by using some sort of certificate.

Advanced Electronic Signature (AES). Article 26. These requirements are:
  • It is uniquely linked to the signatory
  • It is capable of identifying the signatory
  • It is created using electronic signature creation data that the signatory can, with a high level of confidence, use under his sole control
  • It is linked to the data signed therewith in such a way that any subsequent change in the data is detectable.
So, an independent, private and auditable (by EU) service counting on a reliable Identity system, following Personal Data regulations could provide Advanced Signatures compliant with eIDAS.

Qualified Electronic Signature (QES) “means an advanced electronic signature that is created by a qualified electronic signature creation device, and which is based on a qualified certificate for electronic signatures”. Basically, the qualified electronic signature is one based on a Qualified Certificate that can be provide only by Qualified Providers. There is a list in each country in the EU and as I said only these entities are certified to provide Qualified Certificates.

National regulations more or less fit into this definition. For instance, the legal basis for electronic signatures in Ireland are the Electronic Commerce Act, 2000 and the statutory instrument issued Electronic Commerce (Certification Service providers Supervision Scheme) Regulations 2010, S.I. No.233 of 2010.

 

Signature Baselines

About digital signatures according to eIDAS is important to know previously what types of baselines you can provide. There are 4 types of signatures regarding their baselines and hardness:  
  • B: Basic Electronic Signature The lowest and simplest version just containing the SignedInfo, SignatureValue, KeyInfo and SignedProperties. This level combines the old -BES and -EPES levels. This form extends the definition of an electronic signature to conform to the identified signature policy.
  • T: Signature with a timestamp A timestamp regarding the time of signing is added to protect against repudiation.
  • LT: Signature with Long Term Data Certificates and revocation data are embedded to allow verification in future even if their original source is not available. This level is equivalent to the old -XL level.
  • LTA: Signature with Long Term Data and Archive timestamp By using periodical time stamping (e.g. each year) compromising is prevented which could be caused by weakening previous signatures during a long-time storage period. This level is equivalent to the old -A level.  

The EU DSS Project

EU DSS is a framework developed and published by the EU to make possible to Third Parties the implementation of custom solutions involving Digital Signatures being compliant with eIDAS regulation. The framework is HUGE! and it integrates some Open Source tools that will make your life much easier. Besides, the level of integration and quality is really high.

EU DSS supports several technical specifications for digital signatures. These are the main features:

  • XAdES detached and enveloping signatures can be used to sign any file.
  • XAdES enveloped signature can be used to sign an XML file.
  • PDF files can be signed with an enveloped PAdES signature.
  • CAdES enveloping or detached signatures can be used to sign any arbitrary files.
  • ASiC-S or ASiC-E containers can be used to sign at least one document.
  • The multiple parallel signatures can be created.
  • A user can use PKCS#11-compliant QSCD, MS-CAPI, MOCCA and PKCS#12 to sign.
  • Any kind of signature: CAdES, PAdES, XAdES, ASiC-S or ASiC-E can be validated.
  • A validation policy can be applied.
  • Two validation reports are available: Simple and Detailed.
  • The Diagnostic Data representing each static information used during the validation process is available.

I strongly recommend reading the EU DSS documentation as it is really extensive and detailed with tens of examples.

To start using EU DSS in your application the first step is to import its dependencies. In our case E-Sign imports several dependencies focused on PAdES:

libraryDependencies += "commons-logging" % "commons-logging" % "1.2"
val sdDssVersion = "5.5.RC1"
lazy val excludeCommonsLogging = ExclusionRule(organization = "commons-logging", name = "commons-logging")
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-service" % sdDssVersion excludeAll(excludeCommonsLogging)
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-model" % sdDssVersion
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-spi" % sdDssVersion
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-token" % sdDssVersion
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-tsl-validation" % sdDssVersion
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-utils-apache-commons" % sdDssVersion
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-pades" % sdDssVersion
libraryDependencies += "eu.europa.ec.joinup.sd-dss" % "dss-pades-pdfbox" % sdDssVersion excludeAll(excludeCommonsLogging)

The API Solution

The main features of our solution are:

  • eIDAS compliant with Advanced Signatures.
  • It provides the 4 types of baselines, which is not trivial and dramatically important if you're looking for full legal validity.
  • It provides multi-signatory scenarios.
  • It provides document sealing and closing features.
  • The Fexco API includes the immutable E-Ledger as a co-substantial part of the PKI/Digital Signature service, offering the full history of events in time.
  • Full life cycle support, from the creation of the Digital Identity to the validation of signatures.
The main concept for consumers is the Digital Signature Request (DSR). Please find below the description of the DSR:
https://gist.github.com/jesusjavierdediego/c79132f5f17ae484cbaf17b1a498ffbe

We'll see now some key aspects of this service.


Caveats

There are some important lessons learnt that we have to bear in mind:
  • If you add a comma to the document AFTER you apply a signature you are breaking it. In fact, you break ALL the signatures in the document.
  • The only change you can make is to add new signatures. Not the digital signature nor its visual representation are considered as a part of the document's content. This allows to add multiple digital signatures.
  • Multiple digital signatures can be applied to the document, but not simultaneously

 

Application of multiple signatures is always a sequential process

It displays the process of addition of modifications to the document with every new addition of a signature. Because the signing action is partially based on the calculation of the hash a second signature signs the content of the document including the first signature. A third signature validates the content and the first and second signatures. That is the main reason behind the constraint about the concurrent simultaneous application of several signatures on the same document.

So, this constraint makes us to protect the file against eventual Digital Signature Request. In fact, you have to maintain several versions of the document (which is the "logical" document) according to the sequentially applied signatures that can happen along a period of time.

 

Visual representations of signatures

Eventually you can be required to represent the applied digital signatures on a given document. It is remarkable the frequency and volume of the remnant usage of printed files on paper. Please, do not do that. Use the electronic files. However, it seems there still are many institutions and companies using paper documents.Anyway, if you have to meet this requirement you'll have to include the so-called Visual Representations (VR) of the digital signatures. Some caveats:

  • VRs are NOT the digital signatures. The only source of Truth is the digital signature.
  • Ideally the VR is merely informative, not pretending it is the only real signature.
  • VRs are part of the signature and therefore they do not break previous signatures.

Let's see some code

Below snippet shows how the DSS project has been integrated into our E-Sign component. Please, have a look and read the comments. DSS has been written in Java and therefore it can be used in JVM languages project with no restriction. We have used Scala to write the E-Sign component.

import java.io.File
import java.time.Instant
import java.sql.Timestamp
import java.util._
import java.security.KeyStore.PasswordProtection
import java.security.spec.DSAParameterSpec
import java.math.BigInteger
import org.slf4j.LoggerFactory
import eu.europa.esig.dss.enumerations._
import eu.europa.esig.dss.validation.CommonCertificateVerifier
import eu.europa.esig.dss.model.x509.CertificateToken
import eu.europa.esig.dss.model._
import eu.europa.esig.dss.pades._
import eu.europa.esig.dss.pades.signature.PAdESService
import eu.europa.esig.dss.token._
import eu.europa.esig.dss.spi.x509.CommonCertificateSource
import com.fts.cp.esign.utils.{Configuration, Utils, SignatureType}
import com.fts.cp.esign.grpc._
import com.fts.cp.esign.exceptions.DSRException
import com.fts.cp.esign.storage.azblob.CAFilesDAO
import com.fts.cp.esign.model.{SignActionResponse, VisualSignatureDimensions}
  

  @throws(classOf[DSRException])
  def signPDF(
               dsr: DSR,
               idres: IDRes,
               fileToSign: File,
               oc: com.fts.cp.esign.model.OperationalContext,
               sr: com.fts.cp.esign.grpc.SignatureRequest,
               dsc: String
             ): Option[SignActionResponse] = {
    import collection.JavaConverters._

    var result: Option[SignActionResponse] = None
    var pfxPath: String = "" // to be populated later
    try{
      // Conversion to DSS File
      val docToSign: FileDocument = new FileDocument(fileToSign)
     
      val parameters: PAdESSignatureParameters = new PAdESSignatureParameters()
      
      // Some types of signatures have to be visual
      val makeVisual: Boolean = if(
        !sr.`type`.equalsIgnoreCase(SignatureType.RELEASE) &&
          !sr.`type`.equalsIgnoreCase(SignatureType.ETERMS) &&
          !sr.`type`.equalsIgnoreCase(SignatureType.CERTIFICATEDOCUMENT) &&
          sr.representation &&
          !sr.visualRepresentation.get.fieldId.isEmpty
      ) true else false

      val reference = idres.userId.get.piiid + idres.userId.get.entityId
      
      // Get the Digital Identity from our Identity Manager
      val (certToken: CertificateToken, path: String, password: String) = SignatureUtils.getIDItemsFromIDPack(reference, idres.pack.get)
      pfxPath = path
      
      // Set a password protection for the Pkcs12 Signature Token 
      val a = BigInteger.valueOf(passwordParam1)
      val b = BigInteger.valueOf(passwordParam2)
      val c = BigInteger.valueOf(passwordParam3)
      val pp = new PasswordProtection(password.toCharArray(), encryptionAlg, new DSAParameterSpec(a, b, c))
      val signatureToken: Pkcs12SignatureToken = new Pkcs12SignatureToken(pfxPath, pp)
      
      val privateKey: DSSPrivateKeyEntry = signatureToken.getKeys.get(0)
      val keys: List[DSSPrivateKeyEntry] = signatureToken.getKeys()

      //parameters.setSigningCertificate(certToken) // OR..
      parameters.setSigningCertificate(keys.get(0).getCertificate)
      
      /*
      PaDES Signature level. E.g. LTA: Long Term
      You can get this parameter from the Digital Signatrue Request or from teh Configuration
       */
      parameters.setSignatureLevel(SignatureLevel.PAdES_BASELINE_LT)
      
      // Configure the rest of the signature process
      parameters.setDigestAlgorithm(DigestAlgorithm.valueOf(digestAlg))
      parameters.setSignaturePackaging(SignaturePackaging.valueOf(packagingType))
      parameters.setCertificateChain(keys.get(0).getCertificateChain.toList.asJava)
      parameters.setEncryptionAlgorithm(EncryptionAlgorithm.valueOf(encryptionAlg))
      parameters.bLevel.setSigningDate(Date.from(Instant.now))
      parameters.setSignatureSize(signSize * 2) // bytes

      if (makeVisual) {
        parameters.setSignatureFieldId(sr.visualRepresentation.get.fieldId)
      }

      // The DSS Certificate Verifier allows you to add whay you need to ensure ther certificate is validated properly
      val commonCertificateVerifier: CommonCertificateVerifier = new CommonCertificateVerifier()
      commonCertificateVerifier.setTrustedCertSource(new CommonCertificateSource())
      commonCertificateVerifier.setDataLoader(SignatureUtils.getDataLoader())
      commonCertificateVerifier.setCrlSource(SignatureUtils.getCRLSource())
      commonCertificateVerifier.setOcspSource(SignatureUtils.getOcspDataSource())

      // The Timestamp authority can be public and online or private with restricted access
      val service: PAdESService = new PAdESService(commonCertificateVerifier)
      service.setTspSource(SignatureUtils.getOnlineTSP())

      // Get timestamp for the signature
      val tsToken = service.getContentTimestamp(docToSign, parameters)
      val signatureDate = tsToken.getGenerationTime
      val signatureTS: Timestamp = new Timestamp(signatureDate.getTime())

      if (makeVisual) {
        val dimensions = new VisualSignatureDimensions(sr.visualRepresentation.get.fieldId, 0, 0, 0, sr.visualRepresentation.get.width, sr.visualRepresentation.get.length)
        parameters.setSignatureImageParameters(SignatureUtils.getVisualSignatureParams(dsr, idres, oc, dsc, signatureTS.toString, certToken.getSubjectX500Principal.toString, dimensions))
      }

      certToken.getSubjectX500Principal
      val dataToSign: ToBeSigned = service.getDataToSign(docToSign, parameters)
      val digestAlgorithm: DigestAlgorithm = parameters.getDigestAlgorithm()
      
      // Yes, at last this action signs the document
      val signatureValue: SignatureValue = signatureToken.sign(dataToSign, digestAlgorithm, privateKey)
      result = Some(new SignActionResponse(
        service.signDocument(docToSign, parameters, signatureValue),
        signatureTS,
        certToken.getSubjectX500Principal.toString
      ))
      // Delete the password protection as it is not needed anymore
      pp.destroy()
      }catch{
      case e: Exception => {
        val msg = s"Error in DSS Signature process - Reason: ${e}"
        logger.error(msg)
        throw new DSRException(msg)
      }
    }
    // Clean up temporary files from the file system
    Utils.cleanUp()
    result
  }

What happens later?

Once the signature has been applied into the document you'll need a PDF browser to be able to inspect the components in the digital signatures.

The most popular PDF browser is Adobe Acrobat Reader but there are others that are really good. It depends on your OS and preferences. We'll use Acrobat Reader for the next examples.

Acrobat Reader Signature Panel has several constraints. It is a proprietary system and it does not integrate well with OSs. You have to trust on certificates on Acrobat because it manages the certificates and keys in an independent way.

It would be brilliant to have a full integration with the key store in your OS. In this case the user could download the root CA certificate and all certificates issued by this CA should be automatically trusted. However, this is possible ONLY in the Acrobat scope.

To inspect the certificate can be the first thing to do.


Conclusions

  • Digital Signatures are not trivial. This subject requires tons of materials and time of research.
  • A pure and specialized component is not enough. The signatures and documents can be challenged in court. The signatures can be repudiated (the signer assures he/she never signed that document).
  • You need a PKI, a Digital Identity system to manage and provide certificates and keys. Besides, you need to proof the real identity of natural persons, avoiding any chance of impersonation.
  • You need an immutable data system (E-Ledger) to backup your digital signatures by providing secure stored events in time.
  • Only when you have all this rig you can say you are providing a Digital Signature service to deserve the trust of your partners and customers.