org.apache.poi.poifs.crypt.dsig
Class SignatureInfo

java.lang.Object
  extended by org.apache.poi.poifs.crypt.dsig.SignatureInfo
All Implemented Interfaces:
SignatureConfig.SignatureConfigurable

public class SignatureInfo
extends java.lang.Object
implements SignatureConfig.SignatureConfigurable

This class is the default entry point for XML signatures and can be used for validating an existing signed office document and signing a office document.

Validating a signed office document

 OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ);
 SignatureConfig sic = new SignatureConfig();
 sic.setOpcPackage(pkg);
 SignatureInfo si = new SignatureInfo();
 si.setSignatureConfig(sic);
 boolean isValid = si.validate();
 ...
 

Signing an office document

 // loading the keystore - pkcs12 is used here, but of course jks & co are also valid
 // the keystore needs to contain a private key and it's certificate having a
 // 'digitalSignature' key usage
 char password[] = "test".toCharArray();
 File file = new File("test.pfx");
 KeyStore keystore = KeyStore.getInstance("PKCS12");
 FileInputStream fis = new FileInputStream(file);
 keystore.load(fis, password);
 fis.close();
 
 // extracting private key and certificate
 String alias = "xyz"; // alias of the keystore entry
 Key key = keystore.getKey(alias, password);
 X509Certificate x509 = (X509Certificate)keystore.getCertificate(alias);
 
 // filling the SignatureConfig entries (minimum fields, more options are available ...)
 SignatureConfig signatureConfig = new SignatureConfig();
 signatureConfig.setKey(keyPair.getPrivate());
 signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
 OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ_WRITE);
 signatureConfig.setOpcPackage(pkg);
 
 // adding the signature document to the package
 SignatureInfo si = new SignatureInfo();
 si.setSignatureConfig(signatureConfig);
 si.confirmSignature();
 // optionally verify the generated signature
 boolean b = si.verifySignature();
 assert (b);
 // write the changes back to disc
 pkg.close();
 

Implementation notes:

Although there's a XML signature implementation in the Oracle JDKs 6 and higher, compatibility with IBM JDKs is also in focus (... but maybe not thoroughly tested ...). Therefore we are using the Apache Santuario libs (xmlsec) instead of the built-in classes, as the compatibility seems to be provided there.

To use SignatureInfo and its sibling classes, you'll need to have the following libs in the classpath:


Nested Class Summary
 class SignatureInfo.SignaturePart
           
 
Constructor Summary
SignatureInfo()
          Constructor initializes xml signature environment, if it hasn't been initialized before
 
Method Summary
 void confirmSignature()
          add the xml signature to the document
 SignatureConfig getSignatureConfig()
           
 java.lang.Iterable<SignatureInfo.SignaturePart> getSignatureParts()
           
protected static void initXmlProvider()
          Initialize the xml signing environment and the bouncycastle provider
 void postSign(org.w3c.dom.Document document, byte[] signatureValue)
          Helper method for adding informations after the signing.
 DigestInfo preSign(org.w3c.dom.Document document, java.util.List<DigestInfo> digestInfos)
          Helper method for adding informations before the signing.
 void setSignatureConfig(SignatureConfig signatureConfig)
           
 byte[] signDigest(byte[] digest)
          Sign (encrypt) the digest with the private key.
 boolean verifySignature()
           
protected  void writeDocument(org.w3c.dom.Document document)
          Write XML signature into the OPC package
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SignatureInfo

public SignatureInfo()
Constructor initializes xml signature environment, if it hasn't been initialized before

Method Detail

getSignatureConfig

public SignatureConfig getSignatureConfig()
Returns:
the signature config

setSignatureConfig

public void setSignatureConfig(SignatureConfig signatureConfig)
Specified by:
setSignatureConfig in interface SignatureConfig.SignatureConfigurable
Parameters:
signatureConfig - the signature config, needs to be set before a SignatureInfo object is used

verifySignature

public boolean verifySignature()
Returns:
true, if first signature part is valid

confirmSignature

public void confirmSignature()
                      throws javax.xml.crypto.dsig.XMLSignatureException,
                             javax.xml.crypto.MarshalException
add the xml signature to the document

Throws:
javax.xml.crypto.dsig.XMLSignatureException
javax.xml.crypto.MarshalException

signDigest

public byte[] signDigest(byte[] digest)
Sign (encrypt) the digest with the private key. Currently only rsa is supported.

Parameters:
digest - the hashed input
Returns:
the encrypted hash

getSignatureParts

public java.lang.Iterable<SignatureInfo.SignaturePart> getSignatureParts()
Returns:
a signature part for each signature document. the parts can be validated independently.

initXmlProvider

protected static void initXmlProvider()
Initialize the xml signing environment and the bouncycastle provider


preSign

public DigestInfo preSign(org.w3c.dom.Document document,
                          java.util.List<DigestInfo> digestInfos)
                   throws javax.xml.crypto.dsig.XMLSignatureException,
                          javax.xml.crypto.MarshalException
Helper method for adding informations before the signing. Normally confirmSignature() is sufficient to be used.

Throws:
javax.xml.crypto.dsig.XMLSignatureException
javax.xml.crypto.MarshalException

postSign

public void postSign(org.w3c.dom.Document document,
                     byte[] signatureValue)
              throws javax.xml.crypto.MarshalException
Helper method for adding informations after the signing. Normally confirmSignature() is sufficient to be used.

Throws:
javax.xml.crypto.MarshalException

writeDocument

protected void writeDocument(org.w3c.dom.Document document)
                      throws javax.xml.crypto.MarshalException
Write XML signature into the OPC package

Parameters:
document - the xml signature document
Throws:
javax.xml.crypto.MarshalException