XML-Kanonisierung Algorithmus gibt zwei Ergebnisse Unterschied, wenn sie direkt als beim Aufruf als Teil einer digitalen XML-Signatur genannt?

StackOverflow https://stackoverflow.com/questions/1026432

Frage

Ich erhalte zwei unterschiedliche Hashes des gleichen XML-Dokument, wenn ich einige XML direkt canonicalize, als wenn ich eine digitale Signatur auf sie durchführen, die auch die gleiche Kanonisierung algoririth auf dem xml führt, bevor es Hashing? I gearbeitet, dass die digitale Signatur der neuen Zeile Kanonisierungsprobleme Zeichen ‚\ n‘ und Abstands Zeichen enthält, wenn der direkte und Kanonisierung Algorithmus nicht.

Einschließlich der neuen Linie Zeichen + Leerzeichen ist in der Kanonisierung Spezifikation nicht aber? Ich bin speziell bei dieser Version suchen http://www.w3.org / TR / 2001 / REC-xml-C14N-20.010.315

Wer weiß, was los ist? Ich habe die XML-doc und beide Implementierungen des Code enthalten, damit Sie sehen können.

Dies ist verwirrend mich wirklich und ich würde gerne wissen, warum, bin ich etwas fehlt offensichtlich?

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

Der direkte Kanonisierung Code

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

Der digitale XML-Signatur-Code

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

Jede Idee wäre toll! Es ist alles C # -Code durch die Art und Weise.

Vielen Dank im Voraus

Jon

War es hilfreich?

Lösung

Die Art und Weise, in der XML-Sig Leerzeichen behandelt ist, meiner Meinung nach gebrochen. Es ist sicherlich nicht konform mit dem, was die meisten rechtschaffenen Menschen Kanonisierung nennen würde. Ändern Leerzeichen sollte nicht Einfluss auf die verdauen, aber in xmlsig, es tut.

Eine mögliche Abhilfe ist das Dokument durch eine canonicalizer Routine zu durchlaufen, bevor es auf die Erzeugung der Signatur-Code übergeben. Das sollte die Dinge weit besser vorhersagbar machen.

Dieser Artikel könnte helfen klären Dinge.

Andere Tipps

Es sieht aus wie in Ihrem zweiten Stück Code, den Sie haben

xmlDoc.PreserveWhitespace = true;

, während in dem ersten nicht.

Wie ich es verstehe, die Kanonisierung Spezifikation fordert die Leerzeichen zwischen den Elementen zu erhalten, so dass ich schlage vor, Sie sind diese Zeilen in beide.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top