【问题标题】:XML Canonicalization algorithm gives two difference results when called directly than when called as part of an xml digital signature?直接调用 XML 规范化算法与作为 xml 数字签名的一部分调用时,XML 规范化算法会给出两个不同的结果?
【发布时间】:2009-06-22 10:20:33
【问题描述】:

当我直接规范化某些 xml 时,我得到同一个 xml 文档的两个不同哈希值,而不是在对它执行数字签名时,它还在哈希之前对 xml 执行相同的规范化算法?我发现数字签名规范化包括规范化时的换行符 '\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# 代码。

提前致谢

乔恩

【问题讨论】:

    标签: xml digital-signature xml-signature canonical-form


    【解决方案1】:

    在我看来,XML Sig 处理空白的方式是错误的。它当然不符合大多数思想正确的人所说的规范化。更改空格应该影响摘要,但在 xmlsig 中,它会。

    一种可能的解决方法是在将文档传递给签名生成代码之前通过规范化程序例程传递文档。这应该会让事情变得更加可预测。

    This article 可能有助于澄清事情。

    【讨论】:

    • 啊,所以问题不在于 C14n 算法本身,xml 数字签名规范指定在规范化文档时要保留空格和换行符?这是一个我没有意识到的陷阱。在将 xml 传递给签名者之前,我会尝试您关于规范化 xml 的建议。不过,这肯定是倒退的逻辑,W3c 花了所有时间提出规范以将任何 xml 文档转换为规范形式,然后在 xml 数字签名规范中自相矛盾?看起来很奇怪。你知道这是为什么吗?感谢您的帮助!
    【解决方案2】:

    看起来像在你的第二段代码中

    xmlDoc.PreserveWhitespace = true;
    

    一开始你没有。

    据我了解,规范化规范要求保留元素之间的空白,因此我建议您在两者中都包含这一行。

    【讨论】:

      猜你喜欢
      • 2016-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      相关资源
      最近更新 更多