Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ';格式错误的引用元素';添加基于具有SignedXml类的Id属性的引用时_C#_Xml_Soap_Cryptography_Xml Signature - Fatal编程技术网

C# ';格式错误的引用元素';添加基于具有SignedXml类的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

当存在命名空间前缀时,无法按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 = 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。