I have to sign and then countersign some xml with signature. This is my code:
private String singXadesEnveloped(String mode, Document document, Certificate[] certificateChain, PrivateKey signingKey, String mimeType, String encoding)
throws XAdES4jException, ClassCastException, UnsupportedEncodingException, ClassNotFoundException,
InstantiationException, IllegalAccessException {
try {
DataObjectDesc desc = null;
KeyingDataProvider kp = new StaticKeyingDataProvider(certificateChain, signingKey);
BasicSignatureOptionsProvider bop=new BasicSignatureOptionsProvider() {
public boolean signSigningCertificate() {
// TODO Auto-generated method stub
return false;
}
public boolean includeSigningCertificate() {
// TODO Auto-generated method stub
return true;
}
public boolean includePublicKey() {
// TODO Auto-generated method stub
return true;
}
};
//System.out.println("bop.includePublic="+bop.includePublicKey());
XadesSigningProfile sp = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
XadesSigner signer = sp.newSigner();
desc = new DataObjectReference("")
.withDataObjectFormat(new DataObjectFormatProperty(mimeType, encoding))
.withTransform(new EnvelopedSignatureTransform());
SignedDataObjects dataObjects = new SignedDataObjects(desc)
.withCommitmentType(AllDataObjsCommitmentTypeProperty.proofOfOrigin());
Element el = document.getDocumentElement();
//System.out.println("element="+el.getNodeName());
XadesSignatureResult sign = signer.sign(dataObjects, el);
String signed_xml = serializeDocument(document);
//System.out.println("\n\nPodpisany xml:\n"+signed_xml+"\n\n");
XadesSignatureFormatExtender extender = new XadesFormatExtenderProfile().getFormatExtender();
Element sigElem = sign.getSignature().getElement();
//System.out.println("\n\nTag do podpisu:"+sigElem.getNodeName()+"\n\n");
XMLSignature sig = new XMLSignature(sigElem, sigElem.getOwnerDocument().getBaseURI());
XadesSigningProfile profile = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
final XadesSigner counterSigner = profile.newSigner();
// .withTransform(new ExclusiveCanonicalXMLWithoutComments());
//System.out.println("\n\nNode sygnatury: "+sig.getElement().getNodeName()+"\n\n");
Collection<UnsignedSignatureProperty> usp = new ArrayList(1);
usp.add(new CounterSignatureProperty(counterSigner));
extender.enrichSignature(sig, new UnsignedProperties(usp));
} catch (XMLSignatureException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (XMLSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*-----------------------------------------------------*/
//alternatywny sposób realizowania podpisu
//new Enveloped(signer).sign(document.getDocumentElement());
DOMSource domSource = new DOMSource(document);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = tf.newTransformer();
transformer.transform(domSource, result);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println("\n\nsignXades signed before serializedocument: \n\n" + writer.toString());
//return serializeDocument(signed_document);
return writer.toString();
}
It signs my xml and adds counter signature. Unfortunatelly when I verify my xml, the signature veryfies OK, but counter signature not (The digest of signature is not equal with digest from file data).
What is wrong with my code? This is XML with signature and counter signature:
The information is scattered on the comments, so I'm posting the final answer here. The third party tool in use (likely Sigilum Sign, can you confirm?) needs the http://uri.etsi.org/01903#CountersignedSignature
value on the Type
of the main Reference
in the counter signature. XAdES spec states that this reference is not mandatory on this use case of counter signatures, which means the third party tool should accept them. Nevertheless, the latest version of xades4j always includes the element.
If you get the latest version of xades4j on maven this should be fixed. If you got the binaries on the downloads section of xades4j website, please get them again, as the package had a small incoherence.