I have a program running in C# which applies an XMLSignature to an xml document. I have the same XML documents in both cases (C# and Java), but I am not getting the same digest and signature values. I know that the results from my C program are correct, but I dont get to get them correctly in Java.
Here the C# code:
public void SignXml(XmlDocument xmlDoc, RSA Key)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (Key == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
KeyInfo ki = new KeyInfo();
KeyInfoX509Data clause = new KeyInfoX509Data();
clause.AddCertificate(x509_2);
clause.AddIssuerSerial(x509_2.Issuer, x509_2.GetSerialNumberString());
ki.AddClause(clause);
signedXml.KeyInfo = ki;
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
//xmlDoc.Save("antes_firma.xml");
// Append the element to the XML document.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
The Java code is the following:
DOMSignContext dsc = new DOMSignContext (pk, doc.getDocumentElement());
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
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));
KeyInfoFactory kif = fac.getKeyInfoFactory();
X509IssuerSerial issuerSerial = kif.newX509IssuerSerial(cert2.getIssuerDN().getName(), cert.getSerialNumber());
List x509Content = new ArrayList();
x509Content.add(issuerSerial);
x509Content.add(cert2);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
With the same xml document, certificate and private key I am getting the following Digest Values in each one:
Java: EZTMZuMvR9D0WSUgbT2AdFYTBh4=
C#: EsJDdWiUMIOaQp9CC26wQWA6kJ0=
Why does this happen?
Just to add what I did to solve this problem:
String thisLine = "";
String xmlString = "";
BufferedReader br = new BufferedReader(new FileReader(xmlFile));
while ((thisLine = br.readLine()) != null) {
xmlString = xmlString + thisLine.trim();
}
br.close();
ByteArrayInputStream xmlStream = new ByteArrayInputStream(xmlString.getBytes());
xmlDocument = docBuilder.parse(xmlStream);
So, before computing digest and signature, you need to strip whitespace and CRLF when loading xml from file. Otherwise, signature and digest compared to .Net result would be different.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With