5

我正在尝试使用SignedXml 类在 C# 中签名 Xml(实际上是 SOAP xml) ,签名阶段成功通过,但是当我尝试验证签名时它告诉我它无效。我对 MSDN 中的示例所做的唯一更改是使用XmlDsigExcC14NTransform而不是转换 XmlDsigEnvelopedSignatureTransform。如果我使用 XmlDsigEnvelopedSignatureTransform 我会得到一个有效的签名。

这是我的签名代码:

 private static XmlDocument SignXml(XmlDocument doc)
             {
                 SignedXml signedXml = new SignedXml(doc);
                 signedXml.SigningKey = Certificate.PrivateKey;
    
                 Reference reference = new Reference();
                 reference.Uri = "";
                 
                 XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
                 //XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();

                 reference.AddTransform(env);
    
                 signedXml.AddReference(reference);
                 signedXml.ComputeSignature();
    
                 XmlElement signature = signedXml.GetXml();
                 doc.DocumentElement.AppendChild(signature);
                 doc.Save(SignedXmlPath);
                 return doc;
             }

上面的代码会给我一个有效的签名,但如果我使用

XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();

代替

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

我会得到一个无效的签名。

这是我的验证码:

private static bool Verify(XmlDocument doc)
        {
            SignedXml signedDoc = new SignedXml(doc);
            XmlNodeList nodeList = doc.GetElementsByTagName(Constants.SignatureElement);

            signedDoc.LoadXml((XmlElement)nodeList[0]);
            return signedDoc.CheckSignature((RSA)Certificate.PublicKey.Key);
        }

谁能告诉我如何用变换算法签名http://www.w3.org/2001/10/xml-exc-c14n#

提前致谢。

4

1 回答 1

10

您将需要XmlDsigEnvelopedSignatureTransform在您的情况下,因为您要在要签名的元素内添加签名。

XmlDsigEnvelopedSignatureTransform将告诉SignedXml类在测试其有效性之前从签名节点本身中删除签名。这是必需的,因为您在计算签名后添加了该元素。

您可以通过再次调用来添加多个转换,AddTransform如下所示:

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
XmlDsigExcC14NTransform c14n = new XmlDsigExcC14NTransform();

reference.AddTransform(env);
reference.AddTransform(c14n);

但是我认为你真正想要做的而不是我上面的例子是设置CanonicalizationMethod为 c14n:

signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
 - or - 
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
于 2012-12-06T20:43:49.617 回答