Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo.SignaturePart;
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;
import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;
import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.Key;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory;
import java.security.PrivateKey;
import java.util.*;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import java.util.Calendar;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.poifs.crypt.HashAlgorithm;
public class Signer{
private static Calendar cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC);
public static void main(String[] args) throws Exception {
// 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[] = "password".toCharArray();
File file = new File("zzz.pfx");
KeyStore keystore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(file);
keystore.load(fis, password);
fis.close();
// extracting private key and certificate
String alias = "zzz"; // alias of the keystore entry
Key key = keystore.getKey(alias, password);
X509Certificate x509 = (X509Certificate)keystore.getCertificate(alias);
// It is possible, but unnecessary to add CA cert
// CertificateFactory cf = CertificateFactory.getInstance("x509");
// X509Certificate ca = (X509Certificate)cf.generateCertificate(new FileInputStream("rootCA.crt"));
// List<X509Certificate> certChainList = new ArrayList<X509Certificate>();
// certChainList.add(x509);
// certChainList.add(ca);
// Later
// signatureConfig.setSigningCertificateChain(certChainList);
// filling the SignatureConfig entries minimally
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey((PrivateKey)key);
signatureConfig.setExecutionTime(cal.getTime());
signatureConfig.setDigestAlgo(HashAlgorithm.sha1);
// Only use these Signature Facets, the others break Office verification
// see the test Apache POI test code for more facets
signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet());
signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet());
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
OPCPackage pkg = OPCPackage.open("pika.docx", 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
for (SignaturePart sp : si.getSignatureParts()) {
assert sp.validate();
}
assert si.verifySignature();
pkg.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment