使用SignedXml类添加基于Id属性的引用时出现“格式错误的引用元素”

当有名称空间前缀时,无法通过Id属性签署元素:

void Main() { var doc = new XmlDocument(); doc.LoadXml("Zebra"); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = new RSACryptoServiceProvider(); Reference reference = new Reference("#_0"); signedXml.AddReference(reference); signedXml.ComputeSignature(); } 

ComputeSignature()将在这里失败’错误的参考元素’应如何做到这一点?

我们使用的方法是inheritanceSystem.Security.Cryptography.Xml.SignedXml类……

 public class SignedXmlWithId : SignedXml { public SignedXmlWithId(XmlDocument xml) : base(xml) { } public SignedXmlWithId(XmlElement xmlElement) : base(xmlElement) { } public override XmlElement GetIdElement(XmlDocument doc, string id) { // check to see if it's a standard ID reference XmlElement idElem = base.GetIdElement(doc, id); if (idElem == null) { XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable); nsManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement; } return idElem; } } 

var reference = new Reference(“”); //这将签署整个文档

应该注意,您需要使用SignedXmlWithId对象而不是SignedXml对象才能使用重写的GetIdElement()方法。 一旦我这样做,我就能够签署一个XmlElement并绕过格式错误的参考元素错误。

在这里查看关于此主题的post 。

SignedXml不识别u:Id作为有效的XML ID,XML签名确实要求它是XML ID。

您可以使用Schema(http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd,如果您尝试使用WS-Security Id)或将DTD添加到XML片段。 (]>表示XML片段)。 仅向您的LoadXml添加DTD将使SignedXml识别Id,但由于SOAP不允许DTD,因此不要在您的线上SOAP中包含DTD。