Plutext

Digital signatures in Office documents - Java

Dig Sig makes it easy to use docx4j to work with digital signatures:

This Dig Sig tool is part of Plutext's commercial Docx4j Enterprise Edition, but you can still use it if you are using Apache POI or Aspose.Words.

You can download a trial version of Docx4j Enterprise from our products page (including as an Eclipse project ready to run); you’ll also find pricing and ordering info there.

The content below is a high level overview of the material covered more fully in our user manual.

Signatures in Microsoft Office

Signing is part of the Open Packaging Conventions spec.

Docx4j Enterprise can sign documents following that spec; it can also validate signatures.

A signature can be visible (in Excel or Word) or invisible.

In either case, the signature also hashes the document (more on this below), so Office can detect whether its been “tampered” with (ie edited) after signing. This is its primary purpose: to detect whether signed data has been altered

As the spec puts it: Digital signatures do not protect data from being changed. However, consumers can detect whether signed data has been altered and notify the end-user, restrict the display of altered content, or take other actions.

W3C Recommendation

The W3C Recommendation xmldsig-core explains how to generate a signature, and validate it.

The Open Packaging Conventions spec describes how the package digital signature framework applies the W3C Recommendation “XML-Signature Syntax and Processing” with certain modifications.

XAdES

XAdES v1.4.1 extends XMLDSIG into the domain of non-repudiation by defining XML formats for advanced electronic signatures that remain valid over long periods and are compliant with EU-DIR-ESIG. XAdES incorporates additional useful information, including evidence as to validity even if the signer or verifying party later attempts to deny (repudiates) the validity of the signature.

XAdES- EPES is the default format for Office 2010 signatures, and docx4j follows this.

Sample XmlSignaturePart

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:dssi="http://schemas.microsoft.com/office/2006/digsig" xmlns:mdssi="http://schemas.openxmlformats.org/package/2006/digital-signature" xmlns:xd="http://uri.etsi.org/01903/v1.3.2#" Id="idPackageSignature">

  <SignedInfo>

    <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>

    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>

    <Reference Type="http://www.w3.org/2000/09/xmldsig#Object" URI="#idPackageObject">

      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

      <DigestValue>z7n7di9KSx4VqtOfph4aLW2f2v8=</DigestValue>

    </Reference>

    <Reference Type="http://www.w3.org/2000/09/xmldsig#Object" URI="#idOfficeObject">

      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

      <DigestValue>Kj6v0MJbJZSjEvWCJTqJ9Ka1wis=</DigestValue>

    </Reference>

    <Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#idSignedProperties">

      <Transforms>

        <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></Transform>

      </Transforms>

      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

      <DigestValue>ErjZGNguSuMk9yR5GarA7POLx4Y=</DigestValue>

    </Reference>

  </SignedInfo>

<SignatureValue Id="idPackageSignature-signature-value">ejBOZSQY7fK4GcsNH2tfm2TlcwG+..qjO03wwp48BONaBD9GtG3P8jy2GbEsVM23ZaRaBRA==</SignatureValue>

 

  <KeyInfo> <!-- KeyInfoSignatureFacet -->

    <X509Data>

      <X509Certificate>MIIFGDCCBACgAwIBAgIQf9Hy8UJoFT4iDZtsk+..+JhxM8k4JSmlXwk98Oq87tkZ</X509Certificate>

    </X509Data>

  </KeyInfo>

  <Object Id="idPackageObject">

    <Manifest>

      <Reference URI="/word/document.xml?ContentType=application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml">

        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

        <DigestValue>w8hL8o7msdLrxRjyoP0+OXvfOx8=</DigestValue>

      </Reference>

      :

    </Manifest>

    <SignatureProperties Id="id-signature-time-Wed Mar 02 11:11:48 EST 2016">

      <SignatureProperty Id="idSignatureTime" Target="#idPackageSignature">

        <mdssi:SignatureTime>

          <mdssi:Format>YYYY-MM-DDThh:mm:ssTZD</mdssi:Format>

          <mdssi:Value>2016-03-02T00:11:48Z</mdssi:Value>

        </mdssi:SignatureTime>

      </SignatureProperty>

    </SignatureProperties>

  </Object>

  <Object Id="idOfficeObject">

    <SignatureProperties>

      <SignatureProperty Id="idOfficeV1Details" Target="#idPackageSignature">

        <dssi:SignatureInfoV1>

          :

          <dssi:SignatureProviderDetails>0</dssi:SignatureProviderDetails>

          <dssi:SignatureType>1</dssi:SignatureType>

          <dssi:ManifestHashAlgorithm>http://www.w3.org/2000/09/xmldsig#sha1</dssi:ManifestHashAlgorithm>

        </dssi:SignatureInfoV1>

      </SignatureProperty>

    </SignatureProperties>

</Object>

 

  <Object>

    <xd:QualifyingProperties Target="#idPackageSignature">

 

      <xd:SignedProperties Id="idSignedProperties">

        <xd:SignedSignatureProperties>

          <xd:SigningTime>2016-02-02T11:11:48Z</xd:SigningTime>

          <xd:SigningCertificate>

            <xd:Cert>

              <xd:CertDigest>

                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

                <DigestValue>zk1lWOk+1aUEe7B+bZzgO84hQy8=</DigestValue>

              </xd:CertDigest>

              <xd:IssuerSerial>

                <X509IssuerName>[issuer]</X509IssuerName>

                <X509SerialNumber>16990207296591082732488088650</X509SerialNumber>

              </xd:IssuerSerial>

            </xd:Cert>

          </xd:SigningCertificate>

          <xd:SignaturePolicyIdentifier>

            <xd:SignaturePolicyImplied/>

          </xd:SignaturePolicyIdentifier>

          <xd:SignatureProductionPlace>

            <xd:City></xd:City>

            <xd:StateOrProvince></xd:StateOrProvince>

            <xd:PostalCode></xd:PostalCode>

            <xd:CountryName></xd:CountryName>

          </xd:SignatureProductionPlace>

          <xd:SignerRole>

            <xd:ClaimedRoles>

              <xd:ClaimedRole> </xd:ClaimedRole>

            </xd:ClaimedRoles>

          </xd:SignerRole>

        </xd:SignedSignatureProperties>

        <xd:SignedDataObjectProperties>

          <xd:CommitmentTypeIndication>

            <xd:CommitmentTypeId>

              <xd:Identifier>http://uri.etsi.org/01903/v1.2.2#ProofOfOrigin</xd:Identifier>

              <xd:Description>Created and approved this document</xd:Description>

            </xd:CommitmentTypeId>

            <xd:AllSignedDataObjects/>

          </xd:CommitmentTypeIndication>

        </xd:SignedDataObjectProperties>

      </xd:SignedProperties>

 

      <xd:UnsignedProperties>

        <xd:UnsignedSignatureProperties>

          <!-- Office 2013 XAdES-X-L, not implemented in Docx4j 3.3.0 -->

          <xd:CertificateValues>

            <xd:EncapsulatedX509Certificate>MIIE5 .. y6vFUg=</xd:EncapsulatedX509Certificate>

            <xd:EncapsulatedX509Certificate>MIIEZj ..s0AH8g=</xd:EncapsulatedX509Certificate>

          </xd:CertificateValues>

        </xd:UnsignedSignatureProperties>

      </xd:UnsignedProperties>

 

    </xd:QualifyingProperties>

  </Object>

</Signature>