【问题标题】:Malformed Reference Element格式错误的参考元素
【发布时间】:2022-03-24 22:07:36
【问题描述】:

我正在尝试将引用添加到我的安全标头并遇到一个相当普遍的错误:

格式错误的引用元素

我已经尝试了以下类似的结果:

  1. 通过将元素的ID 作为Reference 对象的URI 传递来引用文档中的元素。
  2. 通过LoadXml() 方法将XmlElement 对象传递给Reference。我正在使用this StackOverflow post 上的重载GetIdElement 检索XmlElement 引用。

当我将空字符串作为URI 传递时,SignedXmlComputeSignature() 方法按预期工作。但是,我最多需要添加 3 个对安全标头的引用。

更新 #1
感谢this blog post,我能够从中创建简化版本,我相信导致我的问题是Namespace 属性和前缀的使用。

更新 #2
似乎 <Timestamp> 元素的 Id 属性上的命名空间声明导致发生此错误。

更新 #3
我想我得到了这个工作。请参阅下面的答案。

工作示例:
请注意,定义了命名空间的 Id XAttribute 不起作用;而没有定义命名空间的Id XAttribute 确实有效。

private void CreateSecurityAndTimestampXML(string fileName)
{
    TimestampID = "TS-E" + GUID.NewGuid();
    DateTime SecurityTimestampUTC = DateTime.UtcNow;

    XDocument xdoc = new XDocument(
        new XElement(wsse + "Security",
            new XAttribute(XNamespace.Xmlns + "wsse", wsse.NamespaceName),
            new XAttribute(XNamespace.Xmlns + "wsu", wsu.NamespaceName),
            new XElement(wsu + "Timestamp",
                // new XAttribute(wsu + "Id", TimestampID), // <-- Does Not Work
                new XAttribute("Id", TimestampID), // <-- Works
                new XElement(wsu + "Created", SecurityTimestampUTC.ToString(_timestampFormat)),
                new XElement(wsu + "Expires", SecurityTimestampUTC.AddMinutes(10).ToString(_timestampFormat))
            )
        )
    );

    using (XmlTextWriter tw = new XmlTextWriter(fileName, new UTF8Encoding(false)))
    {
        xdoc.WriteTo(tw);
    }
}

// Snippet
string[] elements = { TimestampID };

foreach (string s in elements)
{
    Reference reference = new Reference()
    {
        Uri = "#" + s
    };

    XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
    env.InclusiveNamespacesPrefixList = _includedPrefixList;
    reference.AddTransform(env);

    xSigned.AddReference(reference);
}

// Add Key Info Here.

// Compute the Signature.
xSigned.ComputeSignature();

【问题讨论】:

    标签: c# x509certificate xml-signature irs


    【解决方案1】:

    看起来,至少目前,让这个工作的答案如下。

    不使用SignedXml 类,而是使用详细的here 类创建一个新的SignedXmlWithId 对象。

    // Create a new XML Document.
    XmlDocument xdoc = new XmlDocument();
    
    xdoc.PreserveWhitespace = true;
    
    // Load the passed XML File using its name.
    xdoc.Load(new XmlTextReader(fileName));
    
    // Create a SignedXml Object.
    //SignedXml xSigned = new SignedXml(xdoc);
    SignedXmlWithId xSigned = new SignedXmlWithId(xdoc); // Use this class instead of the SignedXml class above.
    
    // Add the key to the SignedXml document.
    xSigned.SigningKey = cert.PrivateKey;
    xSigned.Signature.Id = SignatureID;
    xSigned.SignedInfo.CanonicalizationMethod = 
            SignedXml.XmlDsigExcC14NWithCommentsTransformUrl;
    
    //Initialize a variable to contain the ID of the Timestamp element.
    string elementId = TimestampID;
    
    Reference reference = new Reference()
    {
        Uri = "#" + elementId
    };
    
    XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
    env.InclusiveNamespacesPrefixList = _includedPrefixList;
    reference.AddTransform(env);
    
    xSigned.AddReference(reference);
    
    // Add Key Information (omitted)
    
    // Compute Signature
    xSigned.ComputeSignature();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 2014-01-28
      相关资源
      最近更新 更多