/// <summary> /// Signs a XML file using a digital certificate /// </summary> /// <param name="signatureType">The type of signature to perform</param> /// <param name="xml">The XML data to sign represented as byte array</param> /// <param name="certFile">The certificate file to use for signing</param> /// <param name="certPassword">The certificate password</param> /// <param name="signWithSha256">Sign the document using SHA-256</param> /// <returns>The signed data represented as byte array</returns> public static byte[] Sign(XmlSignatureType signatureType, byte[] xml, string certFile, string certPassword, bool signWithSha256 = true) { switch (signatureType) { case XmlSignatureType.Enveloping: return(SignEnvelopingXml(xml, certFile, certPassword, signWithSha256)); default: throw new Exception("Please use a valid XML signature type!"); } }
public static XmlSignatureType Create() { var doc = new XmlSignatureType { SignedInfo = new SignedInfoType { Reference = new List <ReferenceType>() { new ReferenceType { DigestValue = Convert.FromBase64String("qM/+Gsg4/E/0p3fE9LTZA6Xtkds="), }, new ReferenceType { DigestValue = Convert.FromBase64String("mjiR61tL2dV3HMus3GBG/aEjbt4=") } }, }, SignatureValue = new SignatureValueType { Id = "addedSigVal", Value = Convert.FromBase64String(@"VkiVEIkPTISrrwdFouXWEHirxST2mCbLuXmgO0T+4UXHq9Sir+/9gnEZU7Aa2PCB Q/3X0RIkX/sQwGMNdQ5jUJWc0BoGOszhc0CYHxDiayqlQ4fZGz+nhVdoUog4o7Tx dk+vu/LS/7iz6asudXp2Zh8tT4LnOINsj+//DdRd6yM=") }, KeyInfo = new KeyInfoType { }, Object = new List <ObjectType>() { new ObjectType { } }, }; return(doc); }
/// <summary> /// Signs a XML file (enveloping signature) using a digital certificate /// </summary> /// <param name="encodingPath">Used for non-xml, the root path of the document being signed, used for temporary encoding file</param> /// <param name="signatureType">This will be XML or Non-XML</param> /// <param name="xml">The XML data to sign represented as byte array</param> /// <param name="certFile">The certificate file to use for signing</param> /// <param name="certPassword">The certificate password</param> /// <param name="signWithSha256">Sign the document using SHA-256</param> /// <returns>The signed data represented as byte array</returns> private static byte[] SignEnvelopingXml(XmlSignatureType signatureType, byte[] xml, byte[] certFile, string certPassword, bool signWithSha256, string encodingPath = "") { if (xml == null || xml.Length == 0) { // invalid XML array throw new Exception("Nothing to sign!"); } // load certificate X509Certificate2 certificate = LoadSigningCertificate(certFile, certPassword, signWithSha256); if (!certificate.HasPrivateKey) { // invalid certificate throw new Exception("Specified certificate not suitable for signing!"); } using (MemoryStream stream = new MemoryStream(xml)) { // go to the beginning of the stream stream.Flush(); stream.Position = 0; // create new XmlDocument from stream XmlDocument doc = new XmlDocument() { PreserveWhitespace = true }; doc.Load(stream); // create transform (for canonicalization method & reference) XmlDsigExcC14NTransform transform = new XmlDsigExcC14NTransform(); // create new SignedXml from XmlDocument SignedXml signed = GenerateSignedXml(doc, certificate, signWithSha256); } //If this is NOT XML, then we have to convert it and stick it in XML first if (signatureType == XmlSignatureType.NonXML) { //base64 encode it string strEncodedImage; strEncodedImage = System.Convert.ToBase64String(xml, 0, xml.Length); //create a small xml file and put the encoded Image data inside // Create an XmlWriterSettings object with the correct options. XmlWriter writer = null; XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = ("\t"); settings.OmitXmlDeclaration = false; settings.NewLineHandling = NewLineHandling.Replace; settings.CloseOutput = true; string metadataFileName = encodingPath + "\\TempEncoded.xml"; // Create the XmlWriter object and write some content. writer = XmlWriter.Create(metadataFileName, settings); writer.WriteStartElement("Wrapper", ""); writer.WriteString(strEncodedImage); writer.WriteEndElement(); //Close the XmlTextWriter. writer.WriteEndDocument(); writer.Close(); writer.Flush(); xml = File.ReadAllBytes(encodingPath + "\\TempEncoded.xml"); } using (MemoryStream stream = new MemoryStream(xml)) { // go to the beginning of the stream stream.Flush(); stream.Position = 0; // create new XmlDocument from stream XmlDocument doc = new XmlDocument() { PreserveWhitespace = true }; doc.Load(stream); // create transform (for canonicalization method & reference) XmlDsigExcC14NTransform transform = new XmlDsigExcC14NTransform(); // create new SignedXml from XmlDocument SignedXml signed = GenerateSignedXml(doc, certificate, signWithSha256); signed.SignedInfo.CanonicalizationMethod = transform.Algorithm; // get nodes (use XPath to include FATCA declaration) XmlNodeList nodes = doc.DocumentElement.SelectNodes("/*"); // define data object DataObject dataObject = new DataObject() { Data = nodes, Id = "FATCA" }; // add the data we are signing as a sub-element (object) of the signature element signed.AddObject(dataObject); // create reference Reference reference = new Reference(string.Format("#{0}", dataObject.Id)); reference.AddTransform(transform); if (signWithSha256) { // SHA-256 digest reference.DigestMethod = RSAPKCS1SHA256SignatureDescription.ReferenceDigestMethod; } // add reference to document signed.AddReference(reference); // include KeyInfo object & compute signature signed.KeyInfo = CreateKeyInfoFromCertificate(certificate); signed.ComputeSignature(); // get signature XmlElement xmlDigitalSignature = signed.GetXml(); // XML declaration string xmlDeclaration = string.Empty; if (doc.FirstChild is XmlDeclaration) { // include declaration xmlDeclaration = doc.FirstChild.OuterXml; } // return signature as byte array return(Encoding.UTF8.GetBytes(string.Concat(xmlDeclaration, xmlDigitalSignature.OuterXml))); } }
/// <summary> /// Signs a XML file using a digital certificate /// </summary> /// <param name="signatureType">The type of signature to perform</param> /// <param name="xml">The XML data to sign represented as byte array</param> /// <param name="certFile">The certificate file to use for signing</param> /// <param name="certPassword">The certificate password</param> /// <param name="signWithSha256">Sign the document using SHA-256</param> /// <returns>The signed data represented as byte array</returns> public static byte[] Sign(XmlSignatureType signatureType, byte[] xml, string certFile, string certPassword, bool signWithSha256 = true) { switch (signatureType) { case XmlSignatureType.Enveloping: return SignEnvelopingXml(xml, certFile, certPassword, signWithSha256); default: throw new Exception("Please use a valid XML signature type!"); } }