Does Apache POI support signing the word twice?

Viewed 400

I tried to run the signature code twice , but I found that it just geneneral sig1.xml , not sig1.xml and sig2.xml .

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();
2 Answers

Inside org.apache.poi.poifs.crypt.dsig.SignatureInfo there is a method writeDocument(Document document) that creates the sig1.xml overriding the previous one (if any), that's why if you sign it multiple times you will only see the last signature, altough inside the _xmlsignatures/_rels/origin.sigs.rels of the docx/xlsx you can see a relation to each signature.

if you replace:

 sigPartName = PackagingURIHelper.createPartName("/_xmlsignatures/sig1.xml");

with something like:

SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(signatureConfig);
Iterator<?> iterator = si.getSignatureParts().iterator();
int i = 1;
while (iterator.hasNext()) {
   iterator.next();
   i++;
 }
sigPartName = PackagingURIHelper.createPartName("/_xmlsignatures/sig" + i + ".xml");

it will create sig1.xml, sig2.xml, ... and when opening docx/xlsx all signatures will be there.

I've fixed the original issue via #63011, which will be released in POI 4.1.0.

The relevant part of the ticket is.

There's a new config property in SignatureConfig.setAllowMultipleSignatures(true) to allow adding of signatures, which is by default false to stay backward compatible.

Related