C# ';格式错误的引用元素';添加基于具有SignedXml类的Id属性的引用时
当存在命名空间前缀时,无法按Id属性对元素签名:C# ';格式错误的引用元素';添加基于具有SignedXml类的Id属性的引用时,c#,xml,soap,cryptography,xml-signature,C#,Xml,Soap,Cryptography,Xml Signature,当存在命名空间前缀时,无法按Id属性对元素签名: void Main() { var doc = new XmlDocument(); doc.LoadXml("<root xmlns:u=\"myuri\"><test u:Id=\"_0\">Zebra</test></root>"); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey
void Main()
{
var doc = new XmlDocument();
doc.LoadXml("<root xmlns:u=\"myuri\"><test u:Id=\"_0\">Zebra</test></root>");
SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = new RSACryptoServiceProvider();
Reference reference = new Reference("#_0");
signedXml.AddReference(reference);
signedXml.ComputeSignature();
}
void Main()
{
var doc=新的XmlDocument();
doc.LoadXml(“Zebra”);
SignedXml SignedXml=新的SignedXml(doc);
signedXml.SigningKey=新的RSACryptServiceProvider();
引用引用=新引用(“#_0”);
signedXml.AddReference(参考);
signedXml.ComputeSignature();
}
ComputeSignature()
将在此处失败,并带有“格式错误的引用元素”,应如何执行此操作?var Reference=new Reference(“”;///这将对整个文档进行签名签名的XML不将u:Id识别为有效的XML Id,并且XML签名要求它是XML Id
您可以使用模式(http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd 如果您试图使用WS-Security Id)或向XML片段添加DTD。(]>用于XML片段)。仅向LoadXml添加DTD将使SignedXml能够识别Id,但由于SOAP不允许DTD,因此不要将DTD包含在在线SOAP中。我们使用的方法是对
系统.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;
}
}
需要注意的是,您需要使用
SignedXmlWithId
对象而不是SignedXml
对象,以便能够使用重写的GetIdeElement()
方法。一旦我这样做了,我就能够签署一个xmlement
,绕过格式错误的引用元素错误
.但我需要提供要签名的元素的id。.实际的xml是soap信封,使用id似乎就是这样做的。好的,xml有一个attibute“u:id”,如果您将其更改为“…”,那么计算签名应该可以工作。如果您无法更改输入,则必须使用“#xpointer”引用。您是我今天的英雄。谢谢。我也有同样的错误,但问题是SecurePart\Id的值以数字开头(只允许字符)。@JanFriedrich您应该发布一个有效的答案,如果正确,我愿意接受。@JanFriedrich,这也是我的问题。我正在使用SAML请求的ID。必须符合XML ID约定。查看哪个是NCNAME,哪个起始字符受限制。我使用了一个没有大括号的GUID,只是在它前面加了一个u作为ID。