我有一些代码将X509证书插入到肥皂标题中,似乎可以正常工作。
private Message SignMessage(Message request)
{
var doc = new XmlDocument();
var sb = new StringBuilder();
var a = request.CreateBufferedCopy(Int32.MaxValue);
XmlWriter writer = XmlWriter.Create(sb);
a.CreateMessage().WriteMessage(writer);
writer.Close();
doc.LoadXml(sb.ToString());
//This is needed or added the Reference.Uri to the signed Xml will fail
var attr = doc.CreateAttribute("Id");
attr.Value = "MyId";
doc.GetElementsByTagName("s:Body")[0].Attributes.SetNamedItem(attr);
var signed = new SignedXml(doc);
var store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var cert = store.Certificates.Find(X509FindType.FindBySerialNumber, "6e 3c 63 19 bf 19 4b 6d 1b b0 88 1e 57 f0 16 00", true)[0];
signed.SigningKey = cert.PrivateKey;
//Set Reference.Uri
Reference reference = new Reference();
reference.Uri = "#MyId";
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(cert);
keyInfoX509Data.AddSubjectName(cert.IssuerName.Name);
keyInfo.AddClause(keyInfoX509Data);
signed.KeyInfo = keyInfo;
//Add reference to signed xml
signed.AddReference(reference);
signed.ComputeSignature();
XmlElement signature = signed.GetXml();
request = a.CreateMessage();
var element = doc.GetElementsByTagName("s:Header")[0];
element.AppendChild(doc.ImportNode(signature, true));
var xSig = XElement.Parse(element.OuterXml);
foreach (var xElement in xSig.Elements())
{
if (xElement.Name.LocalName == "Signature")
{
//Add signature to header here
var sigDoc = new XmlDocument();
sigDoc.Load(xElement.CreateReader());
var list = new XmlNode[sigDoc.ChildNodes.Item(0).ChildNodes.Count];
for (int x = 0; x < sigDoc.ChildNodes.Item(0).ChildNodes.Count; x++)
{
list[x] = sigDoc.ChildNodes.Item(0).ChildNodes.Item(x);
}
MessageHeader header = MessageHeader.CreateHeader(xElement.Name.LocalName,
xElement.Name.Namespace.NamespaceName, list);
request.Headers.Add(header);
}
}
return request;
}
我现在遇到的问题是如何使用该证书来签署肥皂体元素。我需要soap body元素来匹配MyId
中设置的Reference.Uri
,但似乎无法对body标签进行任何更改。我似乎能够做的就是改变身体的内容,而不是在身体标签本身添加一些东西。
所以目前它看起来像是这样:
<s:Body>
但我需要它看起来像这样:
<s:Body Id="MyId">
我可以通过操纵消息来做到这一点吗?
答案 0 :(得分:0)
Message.CreateMessage(XmlDictionaryReader, Int32, MessageVersion)解决了这个问题。操纵xml,然后从xml创建新消息。