我正在尝试将引用添加到我的安全标头中,并且遇到了一个相当普遍的错误:
格式错误的参考元素
我尝试了以下类似的结果:
ID
元素作为URI
对象的Reference
传入,来引用文档中的元素。XmlElement
方法将Reference
对象传递给LoadXml()
。我使用this StackOverflow post上的重载XmlElement
检索GetIdElement
引用。当我将URI
的空字符串传入时,ComputeSignature()
的{{1}}方法按预期工作。但是,我需要添加最多3个对安全标头的引用。
更新#1
感谢this blog post,我能够从中创建简化版本,我相信导致我的问题的是使用SignedXml
属性和前缀。
更新#2
似乎Namespace
元素的Id
属性上的命名空间声明导致发生此错误。
更新#3
我想我有这个工作。请参阅下面的回答。
工作样本:
请注意,定义了命名空间的<Timestamp>
不起作用;而没有定义命名空间的Id XAttribute
确实有效。
Id XAttribute
答案 0 :(得分:5)
看起来,至少在目前,实现这项工作的答案如下:
使用详细的here类,而不是使用SignedXml
类,创建一个新的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();