XML规范化算法给出了两个差别的结果时相比,当被称为一个XML数字签名的部分,直接叫什么名字?(XM

2019-06-23 20:28发布

我得到了相同的XML文档的两个不同的散列当我直接规范化一些XML比我对其执行数字签名哈希它之前还执行对XML一样规范化algoririth? 我计算出的数字签名的规范化包括新行字符“\ n”和空格字符,并进行规范化的直接算法不的时候。

包括新行字符+空格不是虽然标准化规范? 我专门找在这个版本http://www.w3.org/TR/2001/REC-xml-c14n-20010315

有谁知道这是怎么回事? 我已经包含在XML文档和代码的两种实现,所以你可以看到。

这实在令人费解我,我想知道为什么,我失去了一些东西明显?

<root>
  <child1>some text</child1>
  <child2 attr="1" />
</root>

直接规范化代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Security.Cryptography.Xml;
using System.Security.Cryptography;
using System.IO;
using System.ComponentModel;

namespace XML_SignatureGenerator
{
    class XML_C14N
    {
        private String _filename;
        private Boolean isCommented = false;
        private XmlDocument xmlDoc = null;

        public XML_C14N(String filename)
        {
            _filename = filename;
            xmlDoc = new XmlDocument();
            xmlDoc.Load(_filename);
        }

        //implement this spec http://www.w3.org/TR/2001/REC-xml-c14n-20010315
        public String XML_Canonalize(System.Windows.Forms.RichTextBox tb)
        {
            //create c14n instance and load in xml file
            XmlDsigC14NTransform c14n = new XmlDsigC14NTransform(isCommented);

            c14n.LoadInput(xmlDoc);

            //get canonalised stream
            Stream s1 = (Stream)c14n.GetOutput(typeof(Stream));
            SHA1 sha1 = new SHA1CryptoServiceProvider();
            Byte[] output = sha1.ComputeHash(s1);

            tb.Text = Convert.ToBase64String(output);

            //create new xmldocument and save
            String newFilename = _filename.Substring(0, _filename.Length - 4) + "C14N.xml";
            XmlDocument xmldoc2 = new XmlDocument();
            xmldoc2.Load(s1);
            xmldoc2.Save(newFilename);

            return newFilename;
        }

        public void set_isCommented(Boolean value)
        {
            isCommented = value;
        }

        public Boolean get_isCommented()
        {
            return isCommented;
        }
    }
}

XML数字签名代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

namespace XML_SignatureGenerator
{
class xmlSignature
    {
        public xmlSignature(String filename)
        {
            _filename = filename;
        }

        public Boolean SignXML()
        {
            RSACryptoServiceProvider rsa =  new RSACryptoServiceProvider();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.PreserveWhitespace = true;
            String fname = _filename; //"C:\\SigTest.xml";
            xmlDoc.Load(fname);

            SignedXml xmlSig = new SignedXml(xmlDoc);
            xmlSig.SigningKey = rsa;

            Reference reference = new Reference();
            reference.Uri = "";

            XmlDsigC14NTransform env = new XmlDsigC14NTransform(false);
            reference.AddTransform(env);

            xmlSig.AddReference(reference);
            xmlSig.ComputeSignature();

            XmlElement xmlDigitalSignature = xmlSig.GetXml();
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));

            xmlDoc.Save(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/SignedXML.xml");

            return true;
        }
        private String _filename;
    }
}

任何想法将是巨大的! 这是由所有方式的C#代码。

提前致谢

乔恩

Answer 1:

在XML西格处理空白的方式是,在我看来坏了。 这当然不符合大多数思维正常的人会称之为标准化。 更改空白应该不会影响消化,但在xmlsig,它的作用。

一个可能的解决方法是通过常规canonicalizer它传递给签名生成代码前通过该文档。 这应该遥远的事情,更可预测的做。

这篇文章可能有助于澄清事情。



Answer 2:

它看起来像你的第二个代码段已

xmlDoc.PreserveWhitespace = true;

而在第一你不知道。

据我了解,在canonicalisation规范要求保留元素之间的空白,所以我建议您在这两个行。



文章来源: XML Canonicalization algorithm gives two difference results when called directly than when called as part of an xml digital signature?