/// <summary> /// Tries to sign the specified XML text. /// </summary> /// <param name="xmlText">The XML text.</param> /// <param name="certificate">The certificate.</param> /// <param name="elementName">The name of the element to be signed.</param> /// <param name="elementNamespace">The namespace of the element to be signed.</param> /// <param name="xmlTextSigned">The initial XML text to which the signature was added.</param> /// <param name="useFingerprint">If true the public key of the certificate will be replaced with the fingerprint in the signature.</param> /// <returns>True if the signing was possible, false otherwise.</returns> public static bool TrySignElement(string xmlText, X509Certificate2 certificate, string elementName, string elementNamespace, out string xmlTextSigned, bool useFingerprint = true) { xmlTextSigned = null; var xmlWholeDocument = new XmlDocument(); xmlWholeDocument.PreserveWhitespace = true; xmlWholeDocument.LoadXml(xmlText); if (String.IsNullOrEmpty(elementName)) { return(false); } if (String.IsNullOrEmpty(elementNamespace)) { return(false); } // we are signing only an element (part of the big document) var elements = xmlWholeDocument.GetElementsByTagName(elementName, elementNamespace); if (elements.Count == 0) { return(false); } var elementToSign = elements[0] as XmlElement; var xmlElementDocument = new XmlDocument(); xmlElementDocument.PreserveWhitespace = true; xmlElementDocument.LoadXml(elementToSign.OuterXml); EmandatesSignatureOperationsService.GetOrCreateContextForSignatureAdding getOrCreateContextForSignatureAdding = (doc, elem) => { return(GetOrCreateContextForEmandatesSignatureAdding(doc, elem)); }; //todo cip!! you can optimize this one XmlElement signatureContainer = getOrCreateContextForSignatureAdding(xmlElementDocument, xmlElementDocument.DocumentElement); XmlSignature.Sign(ref xmlElementDocument, certificate, signatureContainer, "", useFingerprint); //var xmlSignature = XmlSignature.Sign(ref doc, certificate, xmlContainerElement, "", null, true); var newnode = xmlWholeDocument.ImportNode(xmlElementDocument.DocumentElement, true); elementToSign.ParentNode.ReplaceChild(newnode, elementToSign); var stringWriter = new StringWriter(); var xmlTextWriter = XmlWriter.Create(stringWriter); xmlWholeDocument.WriteTo(xmlTextWriter); xmlTextWriter.Flush(); xmlTextSigned = stringWriter.GetStringBuilder().ToString(); return(true); }
/// <summary> /// Signs the specified XML text. /// </summary> /// <param name="xmlText">The XML text.</param> /// <param name="certificate">The certificate.</param> /// <param name="useFingerprint">If true the public key of the certificate will be replaced with the fingerprint in the signature.</param> /// <returns>The initial XML text to which the signature was added.</returns> public static string SignDocument(string xmlText, X509Certificate2 certificate, bool useFingerprint = true) { var xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.LoadXml(xmlText); XmlSignature.Sign(ref xmlDoc, certificate, xmlDoc.DocumentElement, "", useFingerprint); var stringWriter = new StringWriter(); var xmlTextWriter = XmlWriter.Create(stringWriter); xmlDoc.WriteTo(xmlTextWriter); xmlTextWriter.Flush(); xmlText = stringWriter.GetStringBuilder().ToString(); return(xmlText); }