使用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。