Package org.apache.poi.poifs.crypt.dsig
Class SignatureInfo
- java.lang.Object
-
- org.apache.poi.poifs.crypt.dsig.SignatureInfo
-
public class SignatureInfo extends java.lang.Object
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 its 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:
- BouncyCastle bcpkix and bcprov (tested against 1.70)
- Apache Santuario "xmlsec" (tested against 2.3.0)
- and log4j-api (tested against 2.17.x)
-
-
Constructor Summary
Constructors Constructor Description SignatureInfo()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
confirmSignature()
add the xml signature to the documentjavax.xml.crypto.dsig.dom.DOMSignContext
createXMLSignContext(org.w3c.dom.Document document)
Convenience method for creating the signature contextjavax.xml.crypto.dsig.keyinfo.KeyInfoFactory
getKeyInfoFactory()
OPCPackage
getOpcPackage()
SignatureConfig
getSignatureConfig()
javax.xml.crypto.dsig.XMLSignatureFactory
getSignatureFactory()
java.lang.Iterable<SignaturePart>
getSignatureParts()
javax.xml.crypto.URIDereferencer
getUriDereferencer()
void
postSign(javax.xml.crypto.dsig.dom.DOMSignContext xmlSignContext, java.lang.String signatureValue)
Helper method for adding informations after the signing.org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo
preSign(javax.xml.crypto.dsig.dom.DOMSignContext xmlSignContext)
Helper method for adding informations before the signing.void
setKeyInfoFactory(javax.xml.crypto.dsig.keyinfo.KeyInfoFactory keyInfoFactory)
void
setOpcPackage(OPCPackage opcPackage)
void
setProvider(java.security.Provider provider)
void
setSignatureConfig(SignatureConfig signatureConfig)
void
setSignatureFactory(javax.xml.crypto.dsig.XMLSignatureFactory signatureFactory)
void
setUriDereferencer(javax.xml.crypto.URIDereferencer uriDereferencer)
java.lang.String
signDigest(javax.xml.crypto.dsig.dom.DOMSignContext xmlSignContext, org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo signedInfo)
Sign (encrypt) the digest with the private key.boolean
verifySignature()
-
-
-
Method Detail
-
getSignatureConfig
public SignatureConfig getSignatureConfig()
- Returns:
- the signature config
-
setSignatureConfig
public void setSignatureConfig(SignatureConfig signatureConfig)
- Parameters:
signatureConfig
- the signature config, needs to be set before a SignatureInfo object is used
-
setOpcPackage
public void setOpcPackage(OPCPackage opcPackage)
-
getOpcPackage
public OPCPackage getOpcPackage()
-
getUriDereferencer
public javax.xml.crypto.URIDereferencer getUriDereferencer()
-
setUriDereferencer
public void setUriDereferencer(javax.xml.crypto.URIDereferencer uriDereferencer)
-
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
- if the signature can't be calculatedjavax.xml.crypto.MarshalException
- if the document can't be serialized
-
createXMLSignContext
public javax.xml.crypto.dsig.dom.DOMSignContext createXMLSignContext(org.w3c.dom.Document document)
Convenience method for creating the signature context- Parameters:
document
- the document the signature is based on- Returns:
- the initialized signature context
-
signDigest
public java.lang.String signDigest(javax.xml.crypto.dsig.dom.DOMSignContext xmlSignContext, org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo signedInfo)
Sign (encrypt) the digest with the private key. Currently only rsa is supported.- Returns:
- the encrypted hash
-
getSignatureParts
public java.lang.Iterable<SignaturePart> getSignatureParts()
- Returns:
- a signature part for each signature document. the parts can be validated independently.
-
preSign
public org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo preSign(javax.xml.crypto.dsig.dom.DOMSignContext xmlSignContext) throws javax.xml.crypto.dsig.XMLSignatureException, javax.xml.crypto.MarshalException
Helper method for adding informations before the signing. NormallyconfirmSignature()
is sufficient to be used.- Throws:
javax.xml.crypto.dsig.XMLSignatureException
javax.xml.crypto.MarshalException
-
postSign
public void postSign(javax.xml.crypto.dsig.dom.DOMSignContext xmlSignContext, java.lang.String signatureValue) throws javax.xml.crypto.MarshalException
Helper method for adding informations after the signing. NormallyconfirmSignature()
is sufficient to be used.- Throws:
javax.xml.crypto.MarshalException
-
setProvider
public void setProvider(java.security.Provider provider)
-
setSignatureFactory
public void setSignatureFactory(javax.xml.crypto.dsig.XMLSignatureFactory signatureFactory)
-
getSignatureFactory
public javax.xml.crypto.dsig.XMLSignatureFactory getSignatureFactory()
-
setKeyInfoFactory
public void setKeyInfoFactory(javax.xml.crypto.dsig.keyinfo.KeyInfoFactory keyInfoFactory)
-
getKeyInfoFactory
public javax.xml.crypto.dsig.keyinfo.KeyInfoFactory getKeyInfoFactory()
-
-