c# - Java 中 XMLSignature 中的 DigestValue 与 C# 不同

标签 c# java xml-signature

我有一个在 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, 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);

使用相同的 xml 文档、证书和私钥,我在每个文件中得到以下摘要值:

  • Java:EZTMZuMvR9D0WSUgbT2AdFYTBh4=

  • C#:EsJDdWiUMIOaQp9CC26wQWA6kJ0=

为什么会这样?

最佳答案

只是添加我为解决此问题所做的工作:

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);

因此,在计算摘要和签名之前,您需要在从文件加载 xml 时去除空格和 CRLF。否则,与 .Net 结果相比,签名和摘要会有所不同。

关于c# - Java 中 XMLSignature 中的 DigestValue 与 C# 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9203478/

相关文章:

c# - 如何在 C# 中动态分配运行时的表格单元格宽度?

java - 如何将 HttpPostedFileBase 文件转换为 Java.Io.InputStream?

java - 单个查询与多个查询

c# - 如何在 .NET 中验证 RSA-SHA512 XML 签名?

c# - Richtextbox 上的编号列表

c# - 在 C# 中从内存中的多个文件创建 Zip 存档

php - 使用 PHP 对远程证书进行 XML 签名验证

java - 由于 xml 签名错误

c# - 如何在 Xamarin.Forms 中创建类似于 Facebook 应用程序的选项卡式页面

java - 如果我将一个对象放入数组中的索引 0 处,如何将那里的对象放入索引 1 处?