7

我们正在从使用 java 的第三方接收签名的 xml。我们的 .NET 实现正确验证签名,除非 xml 包含 字符参考。

看起来 .NET 在 c14n 过程中的某处删除了换行符。

我在 c# 中使用下一个 xml 运行了一些测试:

var xml = "<a>something&#13;\nsomething\r\n</a>";

使用 c14n 的下一个代码:

    public static void c14n(string xml)
    {
        using (MemoryStream msIn = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            var t = new XmlDsigExcC14NTransform(false);
            t.LoadInput(msIn);
            var o = t.GetOutput() as MemoryStream;
            var c14n = Encoding.UTF8.GetString((o as MemoryStream).ToArray());
            Console.WriteLine(c14n);
        }
    }

将产生下一个 xml,它符合w3org规范(每行以 LF 字符结尾):

<a>something&#xD;
something
</a>

但是,当使用下一个代码查看哪个规范表单具有使用 SignedXml .NET 类签名的 xml 时:

public static void SignXml(string xml)
{
    var doc = new XmlDocument { PreserveWhitespace = true };
    doc.LoadXml(xml);

    var cspParams = new CspParameters { KeyContainerName = "XML_DSIG_RSA_KEY" };
    var rsaKey = new RSACryptoServiceProvider(cspParams);

    var signedXml = new SignedXml(doc);
    signedXml.SigningKey = rsaKey;
    var reference = new Reference { Uri = "" };

    var env = new XmlDsigEnvelopedSignatureTransform();
    var excC14NTransform = new XmlDsigExcC14NTransform(false);
    reference.AddTransform(env);
    reference.AddTransform(excC14NTransform);
    reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
    signedXml.AddReference(reference);
    signedXml.ComputeSignature();
    var c14n = Encoding.UTF8.GetString((excC14NTransform.GetOutput() as MemoryStream).ToArray());
    Console.WriteLine(c14n);
}

将产生不同的 xml(每行以 LF char 结尾),我们可以看到换行符 ( ) 已被删除:

<a>something
something
</a>

有没有办法使用 SignedXml 类以便使用正确的规范形式?xml 解析(创建 XmlDocument 时)可能是导致此问题的原因吗?

我想知道这是否是 .NET 中的错误,以及是否有解决方法。

4

0 回答 0