我有一个在C#中运行的程序,它将XMLSignature应用于xml文档.我在两种情况下(C#和Java)都有相同的XML文档,但我没有得到相同的摘要和签名值.我知道我的C程序的结果是正确的,但我不能在Java中正确地得到它们.
这里是C#代码:
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));
}
Java代码如下:
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,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);
使用相同的xml文档,证书和私钥,我在每个文档中获得以下摘要值:
> Java:EZTMZuMvR9D0WSUgbT2AdFYTBh4 =
> C#:EsJDdWiUMIOaQp9CC26wQWA6kJ0 =
为什么会这样?
最佳答案
只是添加我为解决这个问题所做的工作:
原文链接:https://www.f2er.com/java/438011.htmlString 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);
因此,在计算摘要和签名之前,您需要在从文件加载xml时去除空格和CRLF.否则,与.Net结果相比,签名和摘要会有所不同.