Wrong digest value for xml signatures using Java XML Digital Signature API

rundll32

New Member
I need to send a signed XML file to a government agency in Brazil. The problem is that the digest calculated by my Java code (using the Java XML Digital Signature API is different from the one generated with another tool like XMLSEC.Here's the code I use to generate a XML signature for some XML node:private synchronized void sign(XmlObject obj) throws Exception { initKeystore(); XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); List<Transform> transformList = new ArrayList<Transform>(); Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null); Transform c14NTransform = fac.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", (TransformParameterSpec) null); transformList.add(envelopedTransform); transformList.add(c14NTransform); Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null); SignedInfo si = fac.newSignedInfo( fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")), System.getProperty("javax.net.ssl.keyStorePassword").toCharArray()); KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("entry", new KeyStore.PasswordProtection(System.getProperty("javax.net.ssl.keyStorePassword").toCharArray())); X509Certificate cert = (X509Certificate) keyEntry.getCertificate(); // Create the KeyInfo containing the X509Data. KeyInfoFactory kif = fac.getKeyInfoFactory(); X509Data xd = kif.newX509Data(Collections.singletonList(cert)); KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd)); // Instantiate the document to be signed. Element el = (Element) obj.getDomNode().getFirstChild(); String id = el.getAttribute("Id"); DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), el); // Create the XMLSignature, but don't sign it yet. XMLSignature signature = fac.newXMLSignature(si, ki); // Marshal, generate, and sign the enveloped signature. signature.sign(dsc); }If I try to validate the generated XML with xmlsec, I get the following error:$ xmlsec1 --verify consulta.xml func=xmlSecOpenSSLEvpDigestVerify:file=digests.c:line=229:obj=sha1:subj=unknown:error=12:invalid data:data and digest do not matchFAILBut if I try to sign the very same file (consult.xml) with xmlsec (using the same private key), that error goes away:xmlsec1 --sign --output doc-signed.xml --privkey-pem cert.pem consulta.xmlThe differences between consult.xml and doc-signed.xml (generated by xmlsec) are the contents of the SignatureValue and DigestValue tags:consulta.xml:<DigestValue>Ajn+tfX7JQc0HPNJ8KbTy7Q2f8I=</DigestValue>...<SignatureValue>Q1Ys0Rtj8yL2SA2NaQWQPtmNuHKK8q2anPiyLWlH7mOIjwOs0GEcD0WLUM/BZU0QT0kSbDTuJeTR2Ec9wu+hqXXbJ76FpX9/IyHrdyx2hLg0VhB5RRCdyBEuGlmnsFDfXCyBotP+ZyEzolbTCN9TjCUnXNDWtFP1YapMxAIA0sth0lTpYgGJd8CSvFlHdFj+ourf8ZGiDmSTkVkKnqDsj8O0ZLmbZfJpH2CBKicX+Ct7MUz2sqVli4XAHs6WXX+EHJpbOKthS3WCcpG3Kw4K50yIYGTkTbWCYFxOVsMfiVy4W/Qz15Vxb8chD8LM58Epm/szmvnTAESxv/piDr7hyw==</SignatureValue>doc-signed.xml:<DigestValue>w6xElXJrZw3G86OsNkWav+pcKJo=</DigestValue>...<SignatureValue>YmUsnlnAY9uLhlfVBLhB8K8ArxMOkOKZJoQ6zgz55ggU6vJCO9+HWJCKQJp6Rvn/w5PCAFY0KJRbr6/WhHML0Z+Q6TSuIL8OTvJ3iPoROAK6uy07YAflKOUklqk4uxgfMkR+hWMCyfITJVCVZo/MXmPyg7YwmztoSlGH+p6+ND5n2u47Y2k6SpIvw3CUxwAVQkD0Hsj3G58cbUbrFCoyPVGOe4zJ9c1HPsMWKzBEFe3QETzPJ8I1B7EEVi5oDvzXE2rMTH4K7zvNGnXpBNGwnSjEOticlqKVP5wyUD7CPwgF1WgyZ0njvlaW3K8YmAY8fc70v/+wSO6Fu+0zj18Xeg==</SignatureValue>I won't post the rest of either file because they're equal and would make this post even more verbose.From what I can gather, the web app that receives this XML file is a .NET application and it calculates a different signature digest that my Java code (much like xmlsec does). Any ideas?
 
Back
Top