与直接作为xml数字签名的一部分调用时相比,XML Canonicalization算法给出两个不同的结果? [英] XML Canonicalization algorithm gives two difference results when called directly than when called as part of an xml digital signature?

查看:130
本文介绍了与直接作为xml数字签名的一部分调用时相比,XML Canonicalization算法给出两个不同的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我直接规范化某些xml时,与在其上执行数字签名时也对xml执行相同的规范化算法时相比,我在同一个xml文档中得到了两个不同的哈希值?我发现,数字签名规范化包括规范化时的换行字符 \n和空格字符,而直接算法则不包括。

I'm getting two different hashes of the same xml document when I directly canonicalize some xml than when I perform a digital signature on it which also performs the same canonicalization algoririth on the xml before hashing it? I worked out that the digital signature canonicalization includes the new line characters '\n' and spacing characters when canonicalizing and the direct algorithm does not.

包括换行符+空格不是规范化规范吗?我正在专门查看此版本 http://www.w3.org / TR / 2001 / REC-xml-c14n-20010315

Including the new line characters + spaces is not in the canonicalization specification though? I'm specifically looking at this version http://www.w3.org/TR/2001/REC-xml-c14n-20010315

有人知道发生了什么吗?我已经包含了xml文档和代码的两个实现,因此您可以看到。

Does anyone know what is going on? I've included the xml doc and both implementations of the code so you can see.

这真的让我感到困惑,我想知道为什么,我想念吗

This is really puzzling me and I'd like to know why, am I missing something obvious?

<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#代码。

Any idea would be great! It's all C# code by the way.

预先感谢

Jon

推荐答案

XML Sig处理空白的方式已被破坏。当然,这与大多数有正确想法的人所说的规范化都不符。更改空格应该影响摘要,但是在xmlsig中,它确实会影响摘要。

The way in which XML Sig handles whitespace is, in my opinion broken. It's certainly not compliant with what most right-thinking people would call canonicalization. Changing whitespace should not affect the digest, but in xmlsig, it does.

一种可能的解决方法是,在将文档传递给签名生成代码之前,将其通过规范化程序传递。

One possible workaround is to pass the document through a canonicalizer routine before passing it to the signature generation code. That should make things far more predictable.

本文可能有助于澄清问题。

This article might help clarify things.

这篇关于与直接作为xml数字签名的一部分调用时相比,XML Canonicalization算法给出两个不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆