C#XmlDocument在加载时修改数据?

时间:2010-10-12 20:52:48

标签: c# xmldocument

我正在接收来自第三方(其签名的xml)的Base64编码的saml断言。我无法验证签名。仔细检查后,看来当我在SAML xml中读取XmlDocument更改数据时。看到这段代码:

string rawXml = Util.DecodeBase64(SAMLResponse);
byte[] b = Encoding.UTF8.GetBytes(rawXml);
MemoryStream s = new MemoryStream();

s.Write(b, 0, b.Length);
s.Flush();
s.Position = 0;
XmlDocument xml = new XmlDocument();
xml.PreserveWhitespace = true;
xml.Load(s);


MemoryStream s2 = new MemoryStream();
xml.Save(s2);
s2.Position = 0;
byte[] b2 = new byte[s2.Length];
s2.Read(b2, 0, b2.Length);

b的长度为6410字节,其中当我添加

时,b2的长度为6416
int diffcount = 0;
for (int x = 0; x < b2.Length; x++)
{
    if(x > b.Length-1 || b[x]!=b2[x])
    diffcount++;
}

difffcount原来是5572

任何想法如何让xmldocument保留字节值? 感谢

1 个答案:

答案 0 :(得分:0)

同样的困境:csharp,验证传入的SAML签名xml,作为base64编码的xml字符串接收 - 但是从中创建的xml文档将输出少量字节。事实证明,这些不仅是插入.net输出中的自闭元素的额外空间,而且还使用“\ r \ n”表示原始输入字符串只有“\ n”的换行符。

所以现在我测试这些功能的输入字符串(自闭元素没有前面的空格?只有“\ n”用于换行?)然后在整个验证签名的xml(摘要值,签名)的过程中我确保任何中间xml文档都将由[xmlString] .Replace(“/&gt;”,“/&gt;”)和/或[xmlString] .Replace(“\ r \”以相同方式编写的字符串创建。 n“,”\ n“)。这确实有所不同,因此显然.net xml文档内部确实坚持使用它创建的原始输入字符串。

但是有一个例外:还有一个例子,我收到一个xml字符串,没有额外的自闭元素空格,但有完整的“\ r \ n”换行序列。按照我上面提到的程序 - [xmlString] .Replace(“/&gt;”,“/&gt;”) - 我无法复制xml中的SignatureValue和DigestValue;但是,如果在这种情况下我也替换了换行序列 - [xmlString] .Replace(“\ r \ n”,“\ n”) - 我得到了正确的值。显然在这种情况下,SignatureValue和DigestValue首先只用“\ n”作为换行计算,然后 - 当xml文档是Base64编码时 - 使用包含“\ r \ n”的字符串。

为了验证目的,最后只有换行序列的差异似乎很重要,因为自闭合元素的额外空格在规范化(当引入显式结束标记时)之后将消失,这通常在DigestValue和SignatureValue的计算之前。