C#计算并验证SEPA(XML)付款文件的SHA256值

C#计算并验证SEPA(XML)付款文件的SHA256值,c#,xml,sha256,digest,canonicalization,C#,Xml,Sha256,Digest,Canonicalization,我和马库斯·德雷尔一样也在为同样的问题而挣扎: 根据DFÜ协议,我必须计算sha256哈希值: 散列值是使用包含的整个文档(包括开始和结束标记)创建的 文档根据规范化XML 1.0版进行规范化。() 对于包含的文件,也必须根据主文件执行封圣 SHA-256用作哈希算法 这是一个示例有效xml文件(从金融工具导出): 在我的计算中,我得到了以下值: 55B2597B0688AB1A19760B542AA70AEF4F980D7BC9D6EBCF2B741F6299C661D3 但应为文件中的

我和马库斯·德雷尔一样也在为同样的问题而挣扎:

根据DFÜ协议,我必须计算sha256哈希值:

  • 散列值是使用包含的整个文档(包括开始和结束标记)创建的
  • 文档根据规范化XML 1.0版进行规范化。()
  • 对于包含的文件,也必须根据主文件执行封圣
  • SHA-256用作哈希算法
这是一个示例有效xml文件(从金融工具导出):

在我的计算中,我得到了以下值: 55B2597B0688AB1A19760B542AA70AEF4F980D7BC9D6EBCF2B741F6299C661D3 但应为文件中的值: 33E579FE7A9AF6C32C100E8578EBD63E54A2DF47C6849F7A4BC8BEA9E2794197

你们有谁知道我遗漏了什么吗?

看这里,似乎你们遗漏了
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“
来自文档节点的命名空间(可能是因为它被XML解析器剥离了)。我对您的代码做了一些修改,使其使用
using
语法,如果缺少名称空间,我会添加名称空间。现在它返回正确的散列

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.LoadXml(xml);

XmlNodeList list = doc.GetElementsByTagName("Document");

XmlElement node = (XmlElement)list[0];
node.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

string s = node.OuterXml;

// The XmlDsigC14NTransform will strip the UTF8 BOM
using (MemoryStream msIn = new MemoryStream(Encoding.UTF8.GetBytes(s)))
{
    XmlDsigC14NTransform t = new XmlDsigC14NTransform(true);
    t.LoadInput(msIn);

    using (var hash = new SHA256Managed())
    {
        byte[] digest = t.GetDigestedOutput(hash);
        string result = BitConverter.ToString(digest).Replace("-", String.Empty);
    }
}

我认为您希望“规范化”,除非您的XML文档被提升为圣人。更正:canonised->canonicalized。我从说明书上抄了那部分,因为我的英语不太好,我错过了。
System.Text.UTF8Encoding enc = new UTF8Encoding(false);

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(@"path to file");
XmlNodeList list = doc.GetElementsByTagName("Document");
String s = list.Item(0).OuterXml;


MemoryStream msIn = new MemoryStream(enc.GetBytes(s));

XmlDsigC14NTransform t = new XmlDsigC14NTransform(true);
t.LoadInput(msIn);
MemoryStream ms = new MemoryStream();
ms = (MemoryStream)t.GetOutput(typeof(MemoryStream));


byte[] digest = t.GetDigestedOutput(new SHA256Managed());
String result = BitConverter.ToString(digest).Replace("-", String.Empty);
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.LoadXml(xml);

XmlNodeList list = doc.GetElementsByTagName("Document");

XmlElement node = (XmlElement)list[0];
node.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

string s = node.OuterXml;

// The XmlDsigC14NTransform will strip the UTF8 BOM
using (MemoryStream msIn = new MemoryStream(Encoding.UTF8.GetBytes(s)))
{
    XmlDsigC14NTransform t = new XmlDsigC14NTransform(true);
    t.LoadInput(msIn);

    using (var hash = new SHA256Managed())
    {
        byte[] digest = t.GetDigestedOutput(hash);
        string result = BitConverter.ToString(digest).Replace("-", String.Empty);
    }
}