// Sign an XML file and save the signature in a new file. This method does not // save the public key within the XML file. This file cannot be verified unless // the verifying code has the key with which it was signed. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key) { // Create a new XML document. XmlDocument doc = new XmlDocument(); // Load the passed XML file using its name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
static void Main(string[] args) { if (args.Length != 4) { Console.WriteLine("Usage: cra.exe cert-file cert-password input-path output-path"); return; } String certFile = args[0]; String password = args[1]; String input = args[2]; String output = args[3]; X509Certificate2 cert = new X509Certificate2(certFile, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(input); var XmlToSign = new XmlDocument(); XmlToSign.LoadXml(xmlDoc.DocumentElement["Body"].OuterXml); SignedXml signedXml = new SignedXml(XmlToSign); signedXml.SigningKey = cert.PrivateKey; Reference reference = new Reference(); reference.Uri = ""; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDoc.DocumentElement["Body"].AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); xmlDoc.Save(output); }
public static XmlDocument Assinar(XmlDocument docXML, string pUri, X509Certificate2 pCertificado) { try { // Load the certificate from the certificate store. X509Certificate2 cert = pCertificado; // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc = docXML; // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = cert.PrivateKey; // Create a reference to be signed. Reference reference = new Reference(); // pega o uri que deve ser assinada XmlAttributeCollection _Uri = doc.GetElementsByTagName(pUri).Item(0).Attributes; foreach (XmlAttribute _atributo in _Uri) { if (_atributo.Name == "Id") { reference.Uri = "#" + _atributo.InnerText; } } // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } return doc; } catch (Exception ex) { throw new Exception("Erro ao efetuar assinatura digital, detalhes: " + ex.Message); } }
// <Snippet2> // Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, string SubjectName) { if (null == FileName) { throw new ArgumentNullException("FileName"); } if (null == SignedFileName) { throw new ArgumentNullException("SignedFileName"); } if (null == SubjectName) { throw new ArgumentNullException("SubjectName"); } // Load the certificate from the certificate store. X509Certificate2 cert = GetCertificateBySubject(SubjectName); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = cert.PrivateKey; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. // Create an X509IssuerSerial object and add it to the // KeyInfoX509Data object. KeyInfoX509Data kdata = new KeyInfoX509Data(cert); X509IssuerSerial xserial; xserial.IssuerName = cert.IssuerName.ToString(); xserial.SerialNumber = cert.SerialNumber; kdata.AddIssuerSerial(xserial.IssuerName, xserial.SerialNumber); keyInfo.AddClause(kdata); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false))) { doc.WriteTo(xmltw); xmltw.Close(); } }
/// <summary> /// Assinar o documento XML digitalmente /// </summary> /// <param name="FilePath"></param> /// <param name="pUri"></param> /// <param name="oX509Certificate2"></param> /// <returns>XML assinado</returns> public string AssinarDocumentoXML(string FilePath, string pUri, X509Certificate2 oX509Certificate2) { var XML = File.ReadAllText(FilePath); try { var oX509Cert = new X509Certificate2(); var oX509Store = new X509Store("MY", StoreLocation.CurrentUser); oX509Store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); var collection = oX509Store.Certificates; var collection1 = collection.Find(X509FindType.FindBySubjectDistinguishedName, oX509Certificate2.Subject.ToString(), false); if (collection1.Count == 0) { throw new Exception("Framework: Problemas no certificado digital."); } else { oX509Cert = collection1[0]; string x = oX509Cert.GetKeyAlgorithm().ToString(); // Create a new XML document. var oXML = new XmlDocument(); // Format the document to ignore white spaces. oXML.PreserveWhitespace = false; // Load the passed XML file using it’s name. try { oXML.LoadXml(XML); // cheching the elemento will be sign int qtdeRefUri = oXML.GetElementsByTagName(pUri).Count; if (qtdeRefUri == 0) { throw new Exception("Framework: A tag de assinatura " + pUri.Trim() + " não existe"); } else { if (qtdeRefUri > 1) { throw new Exception("Framework: A tag de assinatura " + pUri.Trim() + " não é unica"); } else { try { // Create a SignedXml object. SignedXml signedXml = new SignedXml(oXML); // Add the key to the SignedXml document signedXml.SigningKey = oX509Cert.PrivateKey; // Create a reference to be signed Reference reference = new Reference(); XmlAttributeCollection _Uri = oXML.GetElementsByTagName(pUri).Item(0).Attributes; foreach (XmlAttribute _atributo in _Uri) { if (_atributo.Name == "Id") { reference.Uri = "#" + _atributo.InnerText; } } // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(oX509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // save element on XML oXML.DocumentElement.AppendChild(oXML.ImportNode(xmlDigitalSignature, true)); XmlDocument XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = false; XMLDoc = oXML; // XML document already signed XML = XMLDoc.OuterXml; oXML = null; signedXml = null; env = null; c14 = null; } catch (Exception oError) { throw new Exception("Framework: Erro ao assinar o documento XML." + oError.Message); } } } } catch (Exception oError) { throw new Exception("Framework: XML mal formatado." + oError.Message); } } } catch (Exception oError) { throw new Exception("Framework: Problema ao acessar o certificado digital." + oError.Message); } return(XML); }
// Sign an XML file and save the signature in a new file. This method does not // save the public key within the XML file. This file cannot be verified unless // the verifying code has the key with which it was signed. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key) { // Create a new XML document. XmlDocument doc = new XmlDocument(); // Load the passed XML file using its name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document using ceritificate file. //X509Certificate2 certificate; //using (FileStream fs = // File.Open(CERT_FILE, FileMode.Open)) //using (BinaryReader br = new BinaryReader(fs)) //{ // certificate = // new X509Certificate2( // br.ReadBytes((int)br.BaseStream.Length), "demo"); //} //signedXml.SigningKey = certificate.PrivateKey; // Add the key to the SignedXml document using pre-shared key. signedXml.SigningKey = Key; signedXml.SignedInfo.SignatureMethod = SIGNATURE_ALG; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); reference.DigestMethod = SIGNATURE_DIG; // If you are using certificate, use code below, // and pass the certificate as parameter. //KeyInfo keyInfo = new KeyInfo(); //KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate); //keyInfo.AddClause(keyInfoData); //signedXml.KeyInfo = keyInfo; // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
// Sign an XML file and save the signature in a new file. public static void SignXmlFile(XmlDocument doc, string signedFileName, RSA key) { // Check the arguments. if (doc == null) { throw new ArgumentNullException("doc"); } if (signedFileName == null) { throw new ArgumentNullException("signedFileName"); } if (key == null) { throw new ArgumentNullException("key"); } // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc) { // Add the key to the SignedXml document. SigningKey = key }; // Create a reference to be signed. Reference reference = new Reference { Uri = string.Empty }; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue(key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. if (doc.DocumentElement != null) { doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); } if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(signedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
//public static string RetornarXmlFirmado(string xmlString, string rutaCertificado, string claveCertificado, out string hash) //{ // hash = null; // XmlDocument documentXml = new XmlDocument(); // documentXml.PreserveWhitespace = true; // documentXml.LoadXml(xmlString); // var nodoExtension = documentXml.GetElementsByTagName("ExtensionContent", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2").Item(0); // if (nodoExtension == null) // { // throw new InvalidOperationException("No se pudo encontrar el nodo ExtensionContent en el XML"); // } // nodoExtension.RemoveAll(); // SignedXml firmado = new SignedXml(documentXml); // var xmlSignature = firmado.Signature; // byte[] certificadoByte = File.ReadAllBytes(rutaCertificado); // X509Certificate2 certificado = new X509Certificate2(); // //certificado.Import(certificadoByte, claveCertificado, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); // certificado.Import(certificadoByte, claveCertificado, X509KeyStorageFlags.Exportable); // firmado.SigningKey = certificado.GetRSAPrivateKey(); // //firmado.SigningKey = (RSA)certificado.PrivateKey; // //firmado.SigningKey = certificado.PrivateKey; // //digest info agregada en la seccion firma // var env = new XmlDsigEnvelopedSignatureTransform(); // Reference reference = new Reference(); // reference.AddTransform(env); // reference.Uri = ""; // firmado.AddReference(reference); // firmado.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // var keyInfoData = new KeyInfoX509Data(certificado); // keyInfoData.AddSubjectName(certificado.Subject); // // info para la llave publica // KeyInfo keyInfo = new KeyInfo(); // keyInfo.AddClause(keyInfoData); // //keyInfo.sub // xmlSignature.KeyInfo = keyInfo; // xmlSignature.Id = "signatureKG"; // firmado.ComputeSignature(); // // Recuperamos el valor Hash de la firma para este documento. // if (reference.DigestValue != null) // { // hash = Convert.ToBase64String(reference.DigestValue); // } // XmlNode xmlNodeFirmado = firmado.GetXml(); // xmlNodeFirmado.Prefix = "ds"; // //XmlNode xmlNodeContent = documentXml.CreateElement("ext", "ExtensionContent", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"); // //xmlNodeContent.AppendChild(xmlNodeFirmado); // //XmlNode xmlNode = documentXml.CreateElement("ext", "UBLExtension", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"); // //xmlNode.AppendChild(xmlNodeContent); // nodoExtension.AppendChild(xmlNodeFirmado); // var settings = new XmlWriterSettings() // { // Encoding = Encoding.UTF8, // Indent = true, // IndentChars = "\t", // NewLineChars = Environment.NewLine // }; // string resultado = String.Empty; // using (var memDoc = new MemoryStream()) // { // using (var writer = XmlWriter.Create(memDoc, settings)) // { // //XDocument xDocument = XDocument.Parse(documentXml.OuterXml); // //xDocument.WriteTo(writer); // documentXml.WriteTo(writer); // } // //resultado = Encoding.Unicode.GetString(memDoc.ToArray()); // //resultado = Encoding.GetEncoding("ISO-8859-1").GetString(memDoc.ToArray()); // //resultado = Convert.ToBase64String(memDoc.ToArray()); // resultado = Encoding.UTF8.GetString(memDoc.ToArray()); // } // return resultado; //} public static string RetornarXmlFirmado(string prefijoComprobanteBusqueda, string tnsString, string xmlString, string rutaCertificado, string claveCertificado, out string hash) { hash = null; XmlDocument xmlDocument = new XmlDocument(); xmlDocument.PreserveWhitespace = true; xmlDocument.LoadXml(xmlString); X509Certificate2 certificado = new X509Certificate2(rutaCertificado, claveCertificado); XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDocument.NameTable); nsMgr.AddNamespace("tns", tnsString); nsMgr.AddNamespace("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"); XmlElement elem = xmlDocument.CreateElement("ext:ExtensionContent", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"); xmlDocument.SelectSingleNode($"{prefijoComprobanteBusqueda}/ext:UBLExtensions/ext:UBLExtension", nsMgr).AppendChild(elem); SignedXml signedXml = new SignedXml(xmlDocument); signedXml.SigningKey = certificado.GetRSAPrivateKey(); System.Security.Cryptography.Xml.KeyInfo KeyInfo = new System.Security.Cryptography.Xml.KeyInfo(); System.Security.Cryptography.Xml.Reference Reference = new System.Security.Cryptography.Xml.Reference(); Reference.Uri = ""; Reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); signedXml.AddReference(Reference); X509Chain X509Chain = new X509Chain(); X509Chain.Build(certificado); X509ChainElement local_element = X509Chain.ChainElements[0]; KeyInfoX509Data x509Data = new KeyInfoX509Data(local_element.Certificate); string subjectName = local_element.Certificate.Subject; x509Data.AddSubjectName(subjectName); KeyInfo.AddClause(x509Data); signedXml.Signature.Id = "signatureKG"; signedXml.KeyInfo = KeyInfo; signedXml.ComputeSignature(); XmlElement signature = signedXml.GetXml(); XmlNode dg = signature.GetElementsByTagName("DigestValue", "http://www.w3.org/2000/09/xmldsig#")[0]; XmlNode sg = signature.GetElementsByTagName("SignatureValue", "http://www.w3.org/2000/09/xmldsig#")[0]; hash = dg.InnerText; //SignatureValue = sg.InnerText; signature.Prefix = "ds"; //SetPrefix("ds", signature); elem.AppendChild(signature); MemoryStream msXMLFirmado = new MemoryStream(); xmlDocument.Save(msXMLFirmado); //msXMLFirmado.Position = 1; return(Encoding.UTF8.GetString(msXMLFirmado.ToArray()).Substring(1)); }
public static string Sign(string xml, X509Certificate2 certificate) { if (xml == null) throw new ArgumentNullException("xml"); if (certificate == null) throw new ArgumentNullException("certificate"); if (!certificate.HasPrivateKey) throw new ArgumentException("certificate", "Certificate should have a private key"); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(xml); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = certificate.PrivateKey; // Attach certificate KeyInfo KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; // Attach transforms var reference = new Reference(""); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform(includeComments: false)); reference.AddTransform(new XmlDsigExcC14NTransform(includeComments: false)); signedXml.AddReference(reference); // Compute signature signedXml.ComputeSignature(); var signatureElement = signedXml.GetXml(); // Add signature to bundle doc.DocumentElement.AppendChild(doc.ImportNode(signatureElement, true)); return doc.OuterXml; }
public int AssinarSemID(string XMLString, X509Certificate2 X509Cert) { int resultado = 0; msgResultado = "Assinatura realizada com sucesso"; try { // certificado para ser utilizado na assinatura // //string _xnome = ""; if (X509Cert != null) { // certificado ok string x; x = X509Cert.GetKeyAlgorithm().ToString(); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. try { doc.LoadXml(XMLString); try { // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document signedXml.SigningKey = X509Cert.PrivateKey; // Create a reference to be signed Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(X509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = false; XMLDoc = doc; } catch (Exception caught) { resultado = 7; msgResultado = "Erro: Ao assinar o documento - " + caught.Message; } } catch (Exception caught) { resultado = 3; msgResultado = "Erro: XML mal formado - " + caught.Message; } } } catch (Exception caught) { resultado = 1; msgResultado = "Erro: Problema ao acessar o certificado digital" + caught.Message; //throw new NFeInvalidCertificadoException(msgResultado, ); } return(resultado); }
/// <summary> /// /// Entradas: /// XMLString: string XML a ser assinada /// RefUri : Referência da URI a ser assinada (Ex. infNFe /// X509Cert : certificado digital a ser utilizado na assinatura digital /// /// Retornos: /// Assinar : 0 - Assinatura realizada com sucesso /// 1 - Erro: Problema ao acessar o certificado digital - %exceção% /// 2 - Problemas no certificado digital /// 3 - XML mal formado + exceção /// 4 - A tag de assinatura %RefUri% inexiste /// 5 - A tag de assinatura %RefUri% não é unica /// 6 - Erro Ao assinar o documento - ID deve ser string %RefUri(Atributo)% /// 7 - Erro: Ao assinar o documento - %exceção% /// /// XMLStringAssinado : string XML assinada /// /// XMLDocAssinado : XMLDocument do XML assinado /// /// </summary> /// <param name="XMLString"></param> /// <param name="RefUri"></param> /// <param name="X509Cert"></param> /// <returns></returns> public int VerificarCertificadoEAssinar(string XMLString, string RefUri, X509Certificate2 X509Cert) { int resultado = 0; msgResultado = "Assinatura realizada com sucesso"; try { // certificado para ser utilizado na assinatura // string _xnome = ""; if (X509Cert != null) { _xnome = X509Cert.Subject.ToString(); } X509Certificate2 _X509Cert = new X509Certificate2(); X509Store store = new X509Store("MY", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = store.Certificates; X509Certificate2Collection collection1 = collection.Find(X509FindType.FindBySubjectDistinguishedName, _xnome, false); if (collection1.Count == 0) { resultado = 2; msgResultado = "Problemas no certificado digital"; } else { // certificado ok _X509Cert = collection1[0]; string x; x = _X509Cert.GetKeyAlgorithm().ToString(); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. try { doc.LoadXml(XMLString); // Verifica se a tag a ser assinada existe é única int qtdeRefUri = doc.GetElementsByTagName(RefUri).Count; if (qtdeRefUri == 0) { // a URI indicada não existe resultado = 4; msgResultado = "A tag de assinatura " + RefUri.Trim() + " inexiste"; } // Exsiste mais de uma tag a ser assinada else { if (qtdeRefUri > 1) { // existe mais de uma URI indicada resultado = 5; msgResultado = "A tag de assinatura " + RefUri.Trim() + " não é unica"; } //else if (_listaNum.IndexOf(doc.GetElementsByTagName(RefUri).Item(0).Attributes.ToString().Substring(1,1))>0) //{ // resultado = 6; // msgResultado = "Erro: Ao assinar o documento - ID deve ser string (" + doc.GetElementsByTagName(RefUri).Item(0).Attributes + ")"; //} else { try { // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document signedXml.SigningKey = _X509Cert.PrivateKey; // Create a reference to be signed Reference reference = new Reference(); // pega o uri que deve ser assinada XmlAttributeCollection _Uri = doc.GetElementsByTagName(RefUri).Item(0).Attributes; foreach (XmlAttribute _atributo in _Uri) { if (_atributo.Name == "Id") { reference.Uri = "#" + _atributo.InnerText; } } // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(_X509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = false; XMLDoc = doc; } catch (Exception caught) { resultado = 7; msgResultado = "Erro: Ao assinar o documento - " + caught.Message; } } } } catch (Exception caught) { resultado = 3; msgResultado = "Erro: XML mal formado - " + caught.Message; } } } catch (Exception caught) { resultado = 1; msgResultado = "Erro: Problema ao acessar o certificado digital" + caught.Message; //throw new NFeInvalidCertificadoException(msgResultado, ); } return(resultado); }
public string FirmarXml(string tramaXml) { // Vamos a firmar el XML con la ruta del certificado que está como serializado. var certificate = new X509Certificate2(); certificate.Import(Convert.FromBase64String(RutaCertificadoDigital), PasswordCertificado, X509KeyStorageFlags.MachineKeySet); var xmlDoc = new XmlDocument(); string resultado; using (var documento = new MemoryStream(Convert.FromBase64String(tramaXml))) { xmlDoc.PreserveWhitespace = true; xmlDoc.Load(documento); int tipo; if (TipoDocumento == 1 || TipoDocumento == 2 || TipoDocumento == 3 || TipoDocumento == 4) { tipo = 1; } else { tipo = 0; } var nodoExtension = xmlDoc.GetElementsByTagName("ExtensionContent", CommonExtensionComponents) .Item(tipo); if (nodoExtension == null) { throw new InvalidOperationException("No se pudo encontrar el nodo ExtensionContent en el XML"); } nodoExtension.RemoveAll(); // Creamos el objeto SignedXml. var signedXml = new SignedXml(xmlDoc) { SigningKey = (RSA)certificate.PrivateKey }; signedXml.SigningKey = certificate.PrivateKey; var xmlSignature = signedXml.Signature; var env = new XmlDsigEnvelopedSignatureTransform(); var reference = new Reference(string.Empty); reference.AddTransform(env); xmlSignature.SignedInfo.AddReference(reference); var keyInfo = new KeyInfo(); var x509Data = new KeyInfoX509Data(certificate); x509Data.AddSubjectName(certificate.Subject); keyInfo.AddClause(x509Data); xmlSignature.KeyInfo = keyInfo; xmlSignature.Id = "SignatureErickOrlando"; signedXml.ComputeSignature(); // Recuperamos el valor Hash de la firma para este documento. if (reference.DigestValue != null) { DigestValue = Convert.ToBase64String(reference.DigestValue); } nodoExtension.AppendChild(signedXml.GetXml()); var settings = new XmlWriterSettings() { Encoding = Encoding.GetEncoding("ISO-8859-1") }; using (var memDoc = new MemoryStream()) { using (var writer = XmlWriter.Create(memDoc, settings)) { xmlDoc.WriteTo(writer); } resultado = Convert.ToBase64String(memDoc.ToArray()); } } return(resultado); }
private void CienciaOperacao(object sender, EventArgs e) { // //Ciencia da Operacao // var NFe_Rec = new Recepcao.RecepcaoEventoSoapClient(); NFe_Rec.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySerialNumber, "SERIAL DO CERTIFICADO"); // <- sem espaços e tudo em caixa alta var notas = new string[] { "CHAVES DAS NOTAS" }; // este array não deve passar de 20 elementos, máximo permitido por lote de manifestação var sbXml = new StringBuilder(); sbXml.Append(@"<?xml version=""1.0"" encoding=""UTF-8""?> <envEvento xmlns=""http://www.portalfiscal.inf.br/nfe"" versao=""1.00""> <idLote>1</idLote> "); foreach (var nota in notas) { sbXml.Append(@" <evento xmlns=""http://www.portalfiscal.inf.br/nfe"" versao=""1.00""> <infEvento Id=""ID210210" + nota + @"01""> <cOrgao>91</cOrgao> <tpAmb>1</tpAmb> <CNPJ>CNPJ DA EMPRESA</CNPJ> <chNFe>" + nota + @"</chNFe> <dhEvento>" + DateTime.Now.AddDays(-1).ToString("yyyy-MM-ddTHH:mm:ss") + @"-03:00</dhEvento> <tpEvento>210210</tpEvento> <nSeqEvento>1</nSeqEvento> <verEvento>1.00</verEvento> <detEvento versao=""1.00""> <descEvento>Ciencia da Operacao</descEvento> </detEvento> </infEvento> </evento> "); } sbXml.Append("</envEvento>"); var xml = new XmlDocument(); xml.LoadXml(sbXml.ToString()); var i = 0; foreach (var nota in notas) { var docXML = new SignedXml(xml); docXML.SigningKey = NFe_Rec.ClientCredentials.ClientCertificate.Certificate.PrivateKey; var refer = new Reference(); refer.Uri = "#ID210210" + nota + "01"; refer.AddTransform(new XmlDsigEnvelopedSignatureTransform()); refer.AddTransform(new XmlDsigC14NTransform()); docXML.AddReference(refer); var ki = new KeyInfo(); ki.AddClause(new KeyInfoX509Data(NFe_Rec.ClientCredentials.ClientCertificate.Certificate)); docXML.KeyInfo = ki; docXML.ComputeSignature(); i++; xml.ChildNodes[1].ChildNodes[i].AppendChild(xml.ImportNode(docXML.GetXml(), true)); } var NFe_Cab = new Recepcao.nfeCabecMsg(); NFe_Cab.cUF = "35"; //SP => De acordo com a Tabela de Código de UF do IBGE NFe_Cab.versaoDados = "1.00"; var resp = NFe_Rec.nfeRecepcaoEvento(NFe_Cab, xml); var fileResp = "D:\\Nfe\\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + "-tempResp.xml"; var fileReq = "D:\\Nfe\\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + "-tempRequ.xml"; File.WriteAllText(fileReq, xml.OuterXml); File.WriteAllText(fileResp, resp.OuterXml); System.Diagnostics.Process.Start(fileReq); System.Diagnostics.Process.Start(fileResp); }
private static string AddSignature(X509Certificate2 certificate, string xml, bool useFingerprint, bool addReferenceURI) { var doc = new XmlDocument { PreserveWhitespace = true }; try { doc.LoadXml(xml); } catch (Exception) { return(xml); } // document is empty, parse issue, etc if (doc.DocumentElement == null) { return(xml); } // already has a signature on the root element if (doc.DocumentElement["Signature", SignedXml.XmlDsigNamespaceUrl] != null) { return(xml); } var rsaKey = (RSACryptoServiceProvider)certificate.PrivateKey; var ki = new KeyInfo(); if (useFingerprint) { ki.AddClause(new KeyInfoName(certificate.Thumbprint)); } else { ki.AddClause(new KeyInfoX509Data(certificate)); } var signedXml = new SignedXml(doc) { SigningKey = rsaKey }; var reference = new Reference("") { DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256" }; if (addReferenceURI) { reference.Uri = "#_a75adf55-01d7-40cc-929f-dbd8372ebdfc"; } reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.Signature.SignedInfo.AddReference(reference); signedXml.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.Signature.SignedInfo.SignatureMethod = XmlDsigRsaSha256Url; signedXml.Signature.KeyInfo = ki; signedXml.ComputeSignature(); var signature = signedXml.GetXml().CloneNode(true); doc.DocumentElement.AppendChild(doc.ImportNode(signature, true)); return(doc.OuterXml); }
// Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string XSLString) { // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Create an XmlDsigXPathTransform object using // the helper method 'CreateXPathTransform' defined // later in this sample. XmlDsigXsltTransform XsltTransform = CreateXsltTransform(XSLString); // Add the transform to the reference. reference.AddTransform(XsltTransform); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)Key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
private static void AddSignature(XmlDocument assertionDocument, X509Certificate2 cert) { var signedXml = new SignedXml(assertionDocument); signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.SigningKey = cert.PrivateKey; // Retrieve the value of the "ID" attribute on the root assertion element. var list = assertionDocument.GetElementsByTagName(Assertion.ELEMENT_NAME, Saml2Constants.ASSERTION); var el = (XmlElement)list[0]; var reference = new Reference("#" + el.GetAttribute("ID")); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(reference); // Include the public key of the certificate in the assertion. //signedXml.KeyInfo = new KeyInfo(); //signedXml.KeyInfo.AddClause(new KeyInfoX509Data(cert, X509IncludeOption.WholeChain)); signedXml.ComputeSignature(); // Append the computed signature. The signature must be placed as the sibling of the Issuer element. var nodes = assertionDocument.DocumentElement.GetElementsByTagName("Issuer", Saml2Constants.ASSERTION); if (nodes.Count != 1) { throw new Saml2Exception("Assertion MUST contain one <Issuer> element."); } assertionDocument.DocumentElement.InsertAfter(assertionDocument.ImportNode(signedXml.GetXml(), true), nodes[0]); }
// Sign an XML file and save the signature in a new file. XmlDocument SignParts(SignedMortalityReasonType smrt, Boolean bPart1, Boolean bPart2, X509Certificate2 certificate) { String xmlSource = Serialize(smrt, smrt.GetType()); // Create a SignedXml object. XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlSource); SignedXml signedXml = new SignedXml(doc); // Add parts to be signed if (bPart1) { AddSignatureReference(signedXml, doc, "Part1"); } if (bPart2) { AddSignatureReference(signedXml, doc, "Part2"); } // Get Certificate and signing Key signedXml.SigningKey = certificate.PrivateKey; // Add public key and certificate KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)certificate.PublicKey.Key)); keyInfo.AddClause(new KeyInfoX509Data(certificate)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save it to an XmlElement object. XmlElement xmlSignature = signedXml.GetXml(); doc.PreserveWhitespace = true; XmlNode n = doc.ImportNode(xmlSignature, true); String res = n.OuterXml; String tagName = ""; if (bPart1 && bPart2) { tagName = "AllSignature"; } else if (bPart1) { tagName = "Part1Signature"; } else if (bPart2) { tagName = "Part2Signature"; } XmlNode root = doc.DocumentElement; XmlNode node = root[tagName]; if (node.HasChildNodes == false) { node.AppendChild(n); } else { node.ReplaceChild(n, node.FirstChild); } return(doc); }
//------------------------------------------------------------------------------------------- private string SignXML(string xml) { // Signing XML Documents: http://msdn.microsoft.com/en-us/library/ms229745.aspx var rsaKey = new RSACryptoServiceProvider(); string sales_licensekeys_privatekey = ConfigurationManager.AppSettings["sales_licensekeys_privatekey"]; if (!File.Exists(sales_licensekeys_privatekey)) throw new Exception("The private signing key is missing"); rsaKey.FromXmlString(System.IO.File.ReadAllText(sales_licensekeys_privatekey)); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(xml); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = rsaKey; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // set to "" to sign the entire doc XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); MemoryStream ms = new MemoryStream(); XmlTextWriter writer = new XmlTextWriter(ms, new UTF8Encoding(false)); writer = new XmlTextWriter(ms, new UTF8Encoding(false)); //writer.Formatting = Formatting.Indented; doc.WriteContentTo(writer); writer.Flush(); ms.Position = 0; StreamReader reader = new StreamReader(ms); return reader.ReadToEnd(); }
async Task <FirmadoResponse> ICertificador.FirmarXml(FirmadoRequest request) { var task = Task.Factory.StartNew(() => { var response = new FirmadoResponse(); var certificate = new X509Certificate2(); certificate.Import(Convert.FromBase64String(request.CertificadoDigital), request.PasswordCertificado, X509KeyStorageFlags.MachineKeySet); var xmlDoc = new XmlDocument(); string resultado; var betterBytes = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(Formatos.EncodingIso), Convert.FromBase64String(request.TramaXmlSinFirma)); using (var documento = new MemoryStream(betterBytes)) { xmlDoc.PreserveWhitespace = true; xmlDoc.Load(documento); var indiceNodo = request.UnSoloNodoExtension ? 0 : 1; var nodoExtension = xmlDoc.GetElementsByTagName("ExtensionContent", EspacioNombres.ext) .Item(indiceNodo); if (nodoExtension == null) { throw new InvalidOperationException("No se pudo encontrar el nodo ExtensionContent en el XML"); } nodoExtension.RemoveAll(); // Creamos el objeto SignedXml. var signedXml = new SignedXml(xmlDoc) { SigningKey = certificate.PrivateKey }; var xmlSignature = signedXml.Signature; var env = new XmlDsigEnvelopedSignatureTransform(); var reference = new Reference(string.Empty); reference.AddTransform(env); xmlSignature.SignedInfo.AddReference(reference); var keyInfo = new KeyInfo(); var x509Data = new KeyInfoX509Data(certificate); x509Data.AddSubjectName(certificate.Subject); keyInfo.AddClause(x509Data); xmlSignature.KeyInfo = keyInfo; xmlSignature.Id = "SignOpenInvoicePeru"; signedXml.ComputeSignature(); // Recuperamos el valor Hash de la firma para este documento. if (reference.DigestValue != null) { response.ResumenFirma = Convert.ToBase64String(reference.DigestValue); } response.ValorFirma = Convert.ToBase64String(signedXml.SignatureValue); nodoExtension.AppendChild(signedXml.GetXml()); using (var memDoc = new MemoryStream()) { using (var writer = XmlWriter.Create(memDoc, new XmlWriterSettings { Encoding = Encoding.GetEncoding(Formatos.EncodingIso) })) { xmlDoc.WriteTo(writer); } resultado = Convert.ToBase64String(memDoc.ToArray()); } } response.TramaXmlFirmado = resultado; return(response); }); return(await task); }
public static void SaveCard(InformationCard card, X509Certificate2 cert, string filename) { MemoryStream stream = new MemoryStream(); XmlWriter writer = XmlWriter.Create(stream); writer.WriteStartElement("InformationCard", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteAttributeString("lang", "http://www.w3.org/XML/1998/namespace", "en-US"); writer.WriteStartElement("InformationCardReference", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteElementString("CardId", "http://schemas.xmlsoap.org/ws/2005/05/identity", card.CardReference.CardID); writer.WriteElementString("CardVersion", "http://schemas.xmlsoap.org/ws/2005/05/identity", card.CardReference.CardVersion.ToString()); writer.WriteEndElement(); if (card.CardName != null && card.CardName.Length > 0) { writer.WriteStartElement("CardName", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(card.CardName); writer.WriteEndElement(); } if (card.CardImage != null && card.CardImage.ImageName.Length > 0) { writer.WriteStartElement("CardImage", "http://schemas.xmlsoap.org/ws/2005/05/identity"); if (card.CardImage != null && card.CardImage.ImageMimeType != null && card.CardImage.ImageMimeType.Length > 0) { writer.WriteAttributeString("MimeType", card.CardImage.ImageMimeType); } FileInfo cardImage = new FileInfo(card.CardImage.ImageName); if (cardImage.Exists) { byte[] cardImageBytes = new byte[cardImage.Length]; using (FileStream imageFS = cardImage.OpenRead()) { imageFS.Read(cardImageBytes, 0, cardImageBytes.Length); } string imageBase64 = Convert.ToBase64String(cardImageBytes); writer.WriteString(imageBase64); writer.WriteEndElement(); } } writer.WriteStartElement("Issuer", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(card.Issuer); writer.WriteEndElement(); //writer.WriteStartElement("IssuerName", "http://schemas.xmlsoap.org/ws/2005/05/identity"); //writer.WriteString(card.IssuerName); //writer.WriteEndElement(); writer.WriteStartElement("TimeIssued", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(XmlConvert.ToString(card.TimeIssued, XmlDateTimeSerializationMode.Utc)); writer.WriteEndElement(); writer.WriteStartElement("TimeExpires", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(XmlConvert.ToString(card.TimeExpires, XmlDateTimeSerializationMode.Utc)); writer.WriteEndElement(); writer.WriteStartElement("TokenServiceList", "http://schemas.xmlsoap.org/ws/2005/05/identity"); foreach (TokenService ts in card.TokenServiceList) { EndpointAddressBuilder endpointBuilder = new EndpointAddressBuilder(); endpointBuilder.Uri = new Uri(ts.EndpointReference.Address); endpointBuilder.Identity = new X509CertificateEndpointIdentity(RetrieveCertificate(ts.EndpointReference.Identity)); if (null != ts.EndpointReference.Mex) { MetadataReference mexReference = new MetadataReference(); mexReference.Address = new EndpointAddress(ts.EndpointReference.Mex); mexReference.AddressVersion = AddressingVersion.WSAddressing10; MetadataSection mexSection = new MetadataSection(); mexSection.Metadata = mexReference; MetadataSet mexSet = new MetadataSet(); mexSet.MetadataSections.Add(mexSection); MemoryStream mexMemoryStream = new MemoryStream(); XmlTextWriter mexWriter = new XmlTextWriter(mexMemoryStream, System.Text.Encoding.UTF8); mexSet.WriteTo(mexWriter); mexWriter.Flush(); mexMemoryStream.Seek(0, SeekOrigin.Begin); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(mexMemoryStream, XmlDictionaryReaderQuotas.Max); endpointBuilder.SetMetadataReader(reader); writer.WriteStartElement("TokenService", "http://schemas.xmlsoap.org/ws/2005/05/identity"); EndpointAddress endpoint = endpointBuilder.ToEndpointAddress(); endpoint.WriteTo(AddressingVersion.WSAddressing10, writer); writer.WriteStartElement("UserCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); if (ts.UserCredential.DisplayCredentialHint != null && ts.UserCredential.DisplayCredentialHint.Length > 0) { writer.WriteStartElement("DisplayCredentialHint", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(ts.UserCredential.DisplayCredentialHint); writer.WriteEndElement(); } switch (ts.UserCredential.UserCredentialType) { case CredentialType.UsernameAndPassword: writer.WriteStartElement("UsernamePasswordCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); if (!string.IsNullOrEmpty(ts.UserCredential.Value)) { writer.WriteStartElement("Username", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(ts.UserCredential.Value); writer.WriteEndElement(); } writer.WriteEndElement(); break; case CredentialType.Kerberos: writer.WriteStartElement("KerberosV5Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteEndElement(); break; case CredentialType.SmartCard: writer.WriteStartElement("X509V3Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteStartElement("X509Data", "http://www.w3.org/2000/09/xmldsig#"); if (!string.IsNullOrEmpty(ts.UserCredential.Value)) { writer.WriteStartElement("KeyIdentifier", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); writer.WriteAttributeString("ValueType", null, "http://docs.oasis-open.org/wss/2004/xx/oasis-2004xx-wss-soap-message-security-1.1#ThumbprintSHA1"); writer.WriteString(RetrieveCertificate(ts.UserCredential.Value).Thumbprint); writer.WriteEndElement(); } else { throw new InvalidDataException("No thumbprint was specified"); } writer.WriteEndElement(); writer.WriteEndElement(); break; default: break; } writer.WriteEndElement(); writer.WriteEndElement(); } } writer.WriteEndElement(); //end of tokenservice list // // tokentypes // writer.WriteStartElement("SupportedTokenTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity"); foreach (TokenType tokenType in card.AcceptedTokenTypes) { writer.WriteElementString("TokenType", "http://schemas.xmlsoap.org/ws/2005/02/trust", tokenType.Uri); } writer.WriteEndElement(); // // claims // writer.WriteStartElement("SupportedClaimTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity"); foreach (CardClaim claim in card.SupportedClaimTypeList) { writer.WriteStartElement("SupportedClaimType", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteAttributeString("Uri", claim.Uri); if (!String.IsNullOrEmpty(claim.DisplayTag)) { writer.WriteElementString("DisplayTag", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.DisplayTag); } if (!String.IsNullOrEmpty(claim.Description)) { writer.WriteElementString("Description", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.Description); } writer.WriteEndElement(); } writer.WriteEndElement(); if (card.RequireRPIdentification) { writer.WriteElementString("RequireAppliesTo", "http://schemas.xmlsoap.org/ws/2005/05/identity", card.RequireRPIdentification.ToString()); } if (!String.IsNullOrEmpty(card.PrivacyNotice)) { writer.WriteStartElement("PrivacyNotice", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(card.PrivacyNotice); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Close(); stream.Position = 0; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.Load(stream); SignedXml signed = new SignedXml(); signed.SigningKey = cert.PrivateKey; signed.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference(); reference.Uri = "#_Object_InfoCard"; reference.AddTransform( new XmlDsigExcC14NTransform()); signed.AddReference(reference); KeyInfo info = new KeyInfo(); KeyInfoX509Data certData = new KeyInfoX509Data(cert, X509IncludeOption.WholeChain); info.AddClause(certData); signed.KeyInfo = info; DataObject cardData = new DataObject("_Object_InfoCard", null, null, doc.DocumentElement); signed.AddObject(cardData); signed.ComputeSignature(); XmlElement e = signed.GetXml(); XmlTextWriter fileWriter = new XmlTextWriter(filename, Encoding.UTF8); e.WriteTo(fileWriter); //doc.WriteTo(fileWriter); //Added fileWriter.Flush(); fileWriter.Close(); }
Message OnGetToken(Message input) { MessageBuffer buf = input.CreateBufferedCopy(10000); VerifyInput2(buf); // FIXME: create response message (when I understand what I should return.) // throw new MyException (); //* XmlDocument doc = new XmlDocument(); doc.LoadXml("<Response>RESPONSE</Response>"); X509Certificate2 cert = new X509Certificate2("Test/Resources/test.pfx", "mono"); SignedXml sxml = new SignedXml(doc); MemoryStream ms = new MemoryStream(new byte [] { 1, 2, 3 }); sxml.AddReference(new Reference(ms)); sxml.SigningKey = cert.PrivateKey; sxml.ComputeSignature(); Message msg = Message.CreateMessage(input.Version, "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue", sxml.GetXml()); msg.Headers.Add(MessageHeader.CreateHeader( "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", null, true)); return(msg); //*/ }
/// <summary> /// Signs the specified xml document with the certificate found in /// the local machine matching the provided friendly name and /// referring to the specified target reference ID. /// </summary> /// <param name="certFriendlyName"> /// Friendly Name of the X509Certificate to be retrieved /// from the LocalMachine keystore and used to sign the xml document. /// Be sure to have appropriate permissions set on the keystore. /// </param> /// <param name="xmlDoc"> /// XML document to be signed. /// </param> /// <param name="targetReferenceId"> /// Reference element that will be specified as signed. /// </param> /// <param name="includePublicKey"> /// Flag to determine whether to include the public key in the /// signed xml. /// </param> public void SignXml(string certFriendlyName, IXPathNavigable xmlDoc, string targetReferenceId, bool includePublicKey) { if (string.IsNullOrEmpty(certFriendlyName)) { throw new Saml2Exception(Resources.SignedXmlInvalidCertFriendlyName); } if (xmlDoc == null) { throw new Saml2Exception(Resources.SignedXmlInvalidXml); } if (string.IsNullOrEmpty(targetReferenceId)) { throw new Saml2Exception(Resources.SignedXmlInvalidTargetRefId); } X509Certificate2 cert = _certificateFactory.GetCertificateByFriendlyName(certFriendlyName); if (cert == null) { throw new Saml2Exception(Resources.SignedXmlCertNotFound); } var xml = (XmlDocument)xmlDoc; var signedXml = new SignedXml(xml); signedXml.SigningKey = cert.PrivateKey; if (includePublicKey) { var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; } var reference = new Reference(); reference.Uri = "#" + targetReferenceId; var envelopSigTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelopSigTransform); signedXml.AddReference(reference); signedXml.ComputeSignature(); XmlElement xmlSignature = signedXml.GetXml(); var nsMgr = new XmlNamespaceManager(xml.NameTable); nsMgr.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); nsMgr.AddNamespace("saml", Saml2Constants.NamespaceSamlAssertion); nsMgr.AddNamespace("samlp", Saml2Constants.NamespaceSamlProtocol); XmlNode issuerNode = xml.DocumentElement.SelectSingleNode("saml:Issuer", nsMgr); if (issuerNode != null) { xml.DocumentElement.InsertAfter(xmlSignature, issuerNode); } else { // Insert as a child to the target reference id XmlNode targetNode = xml.DocumentElement.SelectSingleNode("//*[@ID='" + targetReferenceId + "']", nsMgr); targetNode.PrependChild(xmlSignature); } }
public static XmlDocument SignXmlFileSmev3(XmlDocument doc, X509Certificate2 certificate, string signingNodeId, bool assignDs, bool isAck = false, bool isSidebyside = false) { XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable); nsm.AddNamespace("ns", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1"); nsm.AddNamespace("ns1", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1"); nsm.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); SignedXml sxml = new SignedXml(doc) { SigningKey = certificate.PrivateKey }; //=====================================================================================REFERENCE TRASFORMS Reference reference = new Reference { Uri = "#" + signingNodeId, #pragma warning disable 612 //Расчет хеш-суммы ГОСТ Р 34.11-94 http://www.w3.org/2001/04/xmldsig-more#gostr3411 DigestMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete #pragma warning disable 612 }; XmlDsigExcC14NTransform excC14n = new XmlDsigExcC14NTransform(); reference.AddTransform(excC14n); XmlDsigSmevTransform smevTransform = new XmlDsigSmevTransform(); reference.AddTransform(smevTransform); if (isAck) { XmlDsigEnvelopedSignatureTransform enveloped = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(enveloped); } sxml.AddReference(reference); //=========================================================================================CREATE SIGNATURE sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; //Формирование подписи ГОСТ Р 34.10-2001 http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411 sxml.SignedInfo.SignatureMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3410UrlObsolete; KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data X509KeyInfo = new KeyInfoX509Data(certificate); keyInfo.AddClause(X509KeyInfo); sxml.KeyInfo = keyInfo; sxml.ComputeSignature(); XmlElement signature = sxml.GetXml(); //==================================================================================================add ds: if (assignDs) { _assignNsPrefix(signature, "ds"); XmlElement xmlSignedInfo = signature.SelectSingleNode("ds:SignedInfo", nsm) as XmlElement; XmlDocument document = new XmlDocument(); document.PreserveWhitespace = false; document.LoadXml(xmlSignedInfo.OuterXml); //create new canonicalization object based on original one Transform canonicalizationMethodObject = sxml.SignedInfo.CanonicalizationMethodObject; canonicalizationMethodObject.LoadInput(document); //get new hshing object based on original one SignatureDescription description = CryptoConfig.CreateFromName(sxml.SignedInfo.SignatureMethod) as SignatureDescription; if (description == null) { throw new CryptographicException( $"Не удалось создать объект SignatureDescription по имени [{sxml.SignedInfo.SignatureMethod}]"); } HashAlgorithm hash = description.CreateDigest(); if (hash == null) { throw new CryptographicException( $"Не удалось создать объект HashAlgorithm из SignatureDescription по имени [{sxml.SignedInfo.SignatureMethod}]"); } //compute new SignedInfo digest value byte[] hashVal = canonicalizationMethodObject.GetDigestedOutput(hash); //compute new signature XmlElement xmlSignatureValue = signature.SelectSingleNode("ds:SignatureValue", nsm) as XmlElement; xmlSignatureValue.InnerText = Convert.ToBase64String(description.CreateFormatter(sxml.SigningKey).CreateSignature(hashVal)); } //=============================================================================APPEND SIGNATURE TO DOCUMENT if (!isSidebyside) { doc.GetElementsByTagName("CallerInformationSystemSignature", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1")[0].InnerXml = ""; doc.GetElementsByTagName("CallerInformationSystemSignature", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1")[0].AppendChild(signature); } else { getNodeWithAttributeValue(doc.ChildNodes, signingNodeId)?.ParentNode?.AppendChild(signature); } return(doc); }
static int Main(string[] args) { // Verify that an XML document path is provided. if (args.Length != 1 || !File.Exists(args[0])) { Console.Error.WriteLine("Error: You must provide the path to an XML " + "document to sign."); return(1); } // Load the license request file. XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(args[0]); // Get the key pair from the key store. CspParameters parms = new CspParameters(1); // PROV_RSA_FULL parms.Flags = CspProviderFlags.UseMachineKeyStore; // Use Machine store parms.KeyContainerName = "CodeProject"; // "CodeProject" container parms.KeyNumber = 2; // AT_SIGNATURE RSACryptoServiceProvider csp = new RSACryptoServiceProvider(parms); // Creating the XML signing object. SignedXml sxml = new SignedXml(xmldoc); sxml.SigningKey = csp; // Set the canonicalization method for the document. sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl; // No comments. // Create an empty reference (not enveloped) for the XPath // transformation. Reference r = new Reference(""); // Create the XPath transform and add it to the reference list. r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false)); // Add the reference to the SignedXml object. sxml.AddReference(r); // Compute the signature. sxml.ComputeSignature(); // Get the signature XML and add it to the document element. XmlElement sig = sxml.GetXml(); xmldoc.DocumentElement.AppendChild(sig); // Write-out formatted signed XML to console (allow for redirection). XmlTextWriter writer = new XmlTextWriter(Console.Out); writer.Formatting = Formatting.Indented; try { xmldoc.WriteTo(writer); } finally { writer.Flush(); writer.Close(); } return(0); }
public XmlDocument assinarXML(XmlDocument documentoXML, X509Certificate2 certificadoX509, string tagAAssinar, string idAtributoTag) { // Variáveis utilizadas na assinatura XmlNodeList nodeParaAssinatura = null; SignedXml signedXml = null; Reference reference = null; KeyInfo keyInfo = null; XmlElement sig = null; XmlDocument xmlAssinado = null; bool temChavePrivada = false; bool eValido = true; if (eValido) { // Verifica se o certificado passado por parâmetro possui chave privada. // Se não for possível verificar se o certificado tem ou não a chave privada, significa que // a instância do objeto X509Certificate2 está nula. try { temChavePrivada = certificadoX509.HasPrivateKey; } catch (Exception ex) { // Objeto X509Certificate2 passado por parâmetro está nulo MessageBox.Show("Objeto X509Certificate2 passado por parâmetro não foi carregado." + ex.Message); } if (temChavePrivada) { if (!tagAAssinar.Equals(string.Empty)) { if (!idAtributoTag.Equals(string.Empty)) { try { // Informando qual a tag será assinada nodeParaAssinatura = documentoXML.GetElementsByTagName(tagAAssinar); signedXml = new SignedXml((XmlElement)nodeParaAssinatura[0]); signedXml.SignedInfo.SignatureMethod = signatureMethod; RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)certificadoX509.PrivateKey; if (!privateKey.CspKeyContainerInfo.HardwareDevice) { CspKeyContainerInfo enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo; CspParameters cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, privateKey.CspKeyContainerInfo.KeyContainerName); if (privateKey.CspKeyContainerInfo.MachineKeyStore) { cspparams.Flags |= CspProviderFlags.UseMachineKeyStore; } privateKey = new RSACryptoServiceProvider(cspparams); } // Adicionando a chave privada para assinar o documento signedXml.SigningKey = privateKey; // Referenciando o identificador da tag que será assinada reference = new Reference("#" + nodeParaAssinatura[0].Attributes[idAtributoTag].Value); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform(false)); reference.AddTransform(new XmlDsigC14NTransform(false)); reference.DigestMethod = digestMethod; // Adicionando a referencia de qual tag será assinada signedXml.AddReference(reference); // Adicionando informações do certificado na assinatura keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificadoX509)); signedXml.KeyInfo = keyInfo; // Calculando a assinatura signedXml.ComputeSignature(); // Adicionando a tag de assinatura ao documento xml sig = signedXml.GetXml(); documentoXML.GetElementsByTagName(tagAAssinar)[0].ParentNode.AppendChild(sig); xmlAssinado = new XmlDocument(); xmlAssinado.PreserveWhitespace = true; xmlAssinado.LoadXml(documentoXML.OuterXml); } catch (Exception ex) { // Falha ao assinar documento XML error = ex.Message; errorTime = DateTime.Now; LogErMsg(); MessageBox.Show("Falha ao assinar documento XML, detalhes do erro foi gerado no log C:'\'Reinf'\'log." + ex.Message); } } else { // String que informa o id da tag XML a ser assinada está vazia error = "String que informa o id da tag XML a ser assinada está vazia"; errorTime = DateTime.Now; LogErMsg(); MessageBox.Show("String que informa o id da tag XML a ser assinada está vazia"); } } else { // String que informa a tag XML a ser assinada está vazia error = "String que informa a tag XML a ser assinada está vazia"; errorTime = DateTime.Now; LogErMsg(); MessageBox.Show("String que informa a tag XML a ser assinada está vazia"); } } else { // Certificado Digital informado não possui chave privada error = "Certificado Digital informado não possui chave privada"; errorTime = DateTime.Now; LogErMsg(); MessageBox.Show("Certificado Digital informado não possui chave privada"); } } return(xmlAssinado); }
//tutorial - https://www.asptricks.net/2015/09/sign-xmldocument-with-x509certificate2.html internal static XmlDocument GetSignedXMLDocument(XmlDocument xmlDocument, X509Certificate2 certificate, long procedureSerial = -1, string reason = "") { //Before signing, should check if current document sign is valid or not, if current document is invalid, then new sign should not be added - not implemented yet, but should be if (CheckIfDocumentPreviouslySigned(xmlDocument)) { bool?isLastSignVerified = VerifyLastSign(xmlDocument); if (isLastSignVerified == false) { MessageBox.Show("The file was TEMPERED after last sign !!"); return(null); //Last Sign Not Verified } } //Then sign the xml try { //MessageBox.Show(certificate.Subject); SignedXml signedXml = new SignedXml(xmlDocument); signedXml.SigningKey = certificate.PrivateKey; // Create a reference to be signed Reference reference = new Reference(); ///////////////////// reference.Uri = ""; //"#" + procedureSerial; //reference.Type = reason; //reference.Id = DateTime.UtcNow.Ticks.ToString(); Tsa tsa = new Tsa(); string signedTsaString = tsa.GetSignedHashFromTsa(xmlDocument); DateTime?tsaTime = Tsa.GetTsaTimeFromSignedHash(signedTsaString); //reference.Id = Base64EncodedCurrentTime(tsaTime); reference.Id = signedTsaString; //bool status = Tsa.ValidateTimestamp(xmlDocument, reference.Id); //reference.TransformChain = ; ///////////////////// // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(true); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); //canonicalize XmlDsigC14NTransform c14t = new XmlDsigC14NTransform(); reference.AddTransform(c14t); KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate); KeyInfoName kin = new KeyInfoName(); //kin.Value = "Public key of certificate"; kin.Value = certificate.FriendlyName; RSA rsa = (RSA)certificate.PublicKey.Key; RSAKeyValue rkv = new RSAKeyValue(rsa); keyInfo.AddClause(rkv); keyInfo.AddClause(kin); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; //////////////////////////////////////////Add Other Data as we need//// // Add the data object to the signature. //CreateMetaDataObject("Name", GetNetworkTime()); signedXml.AddObject(CreateMetaDataObject(procedureSerial, reason)); /////////////////////////////////////////////////////////////////////// // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDocument.DocumentElement.AppendChild( xmlDocument.ImportNode(xmlDigitalSignature, true) ); ///////////////////// } catch (Exception exception) { MessageBox.Show("Internal System Error during sign"); throw exception; } return(xmlDocument); }
public static string assinaXML(string XMLString, string RefUri, X509Certificate2 X509Cert) { XmlDocument XMLDoc; try { string _xnome = ""; if (X509Cert != null) { _xnome = X509Cert.Subject.ToString(); } X509Certificate2 _X509Cert = new X509Certificate2(); X509Store store = new X509Store("MY", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection collection1 = (X509Certificate2Collection)collection.Find(X509FindType.FindBySubjectDistinguishedName, _xnome, false); if (collection1.Count == 0) { throw new Exception("Problemas no certificado digital"); } else { _X509Cert = collection1[0]; string x; x = _X509Cert.GetKeyAlgorithm().ToString(); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; try { doc.LoadXml(XMLString); int qtdeRefUri = doc.GetElementsByTagName(RefUri).Count; if (qtdeRefUri == 0) { throw new Exception("A tag de assinatura " + RefUri.Trim() + " inexiste"); } else { if (qtdeRefUri > 1) { throw new Exception("A tag de assinatura " + RefUri.Trim() + " não é unica"); } else { try { SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = _X509Cert.PrivateKey; Reference reference = new Reference(); XmlAttributeCollection _Uri = doc.GetElementsByTagName(RefUri).Item(0).Attributes; foreach (XmlAttribute _atributo in _Uri) { if (_atributo.Name == "Id") { reference.Uri = "#" + _atributo.InnerText; } } XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); signedXml.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(_X509Cert)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = false; XMLDoc = doc; return(XMLDoc.OuterXml); } catch (Exception caught) { throw new Exception("Erro: Ao assinar o documento - " + caught.Message); } } } } catch (Exception caught) { throw new Exception("Erro: XML mal formado - " + caught.Message); } } } catch (Exception caught) { throw new Exception("Erro: Problema ao acessar o certificado digital" + caught.Message); } }
public static SignatureType GeraAssinatura(XmlDocument doc, string pUri, X509Certificate2 cert) { try { var signature = doc.GetElementsByTagName("Signature"); if (signature.Count == 1) { signature.Item(0).ParentNode.RemoveChild(signature.Item(0)); } else if (signature.Count > 1) { throw new InvalidOperationException("Não é possível assinar um documento com mais de uma assinatura existente."); } // Create a SignedXml object. var signedXml = new SignedXml(doc) { SigningKey = cert.PrivateKey }; // Create a reference to be signed. var reference = new Reference(); // pega o uri que deve ser assinada var uri = doc.GetElementsByTagName(pUri).Item(0).Attributes; foreach (XmlAttribute atributo in uri) { if (atributo.Name == "Id") { reference.Uri = "#" + atributo.InnerText; } } // Add an enveloped transformation to the reference. var env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); var c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. var keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); var xml = signedXml.GetXml(); using (var sw = new StringWriter()) using (var xw = new XmlTextWriter(sw)) { xml.WriteTo(xw); xw.Close(); var sigXml = sw.ToString(); return(SignatureType.Deserialize(sigXml)); } } catch (Exception ex) { throw new Exception("Erro ao efetuar assinatura digital, detalhes: " + ex.Message); } }
// Sign an XML file. // This document cannot be verified unless the verifying // code has the key with which it was signed. public static void SignXml(XmlDocument xmlDoc, RSA Key) { // Check arguments. if (xmlDoc == null) { throw new ArgumentException("xmlDoc"); } if (Key == null) { throw new ArgumentException("Key"); } // Create a SignedXml object. SignedXml signedXml = new SignedXml(xmlDoc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); }
// Sign an XML file and save the signature in a new file. This method does not // save the public key within the XML file. This file cannot be verified unless // the verifying code has the key with which it was signed. public static void SignXmlFile(string fileName, string signedFileName) { //var cspParams = new CspParameters { KeyContainerName = "XML_DSIG_RSA_KEY" }; //var key = new RSACryptoServiceProvider(cspParams); //var blob = key..ExportCspBlob(true); //var cert = new X509Certificate2(blob); //File.WriteAllBytes("Hello.cer", cert.Export(X509ContentType.Cert)); var cert = new X509Certificate2("certificate.pfx"); var privateKey = cert.PrivateKey as RSACryptoServiceProvider; // Create a new XML document. XmlDocument doc = new XmlDocument(); // Load the passed XML file using its name. doc.Load(new XmlTextReader(fileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = privateKey; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); var keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue(cert.PublicKey.Key as RSACryptoServiceProvider)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(signedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
/// <summary> /// Obtém a assinatura de um objeto serializável /// </summary> /// <typeparam name="T"></typeparam> /// <param name="objeto"></param> /// <param name="id"></param> /// <param name="certificadoDigital">Informe o certificado digital</param> /// <param name="manterDadosEmCache">Validador para manter o certificado em cache</param> /// <param name="signatureMethod"></param> /// <param name="digestMethod"></param> /// <param name="cfgServicoRemoverAcentos"></param> /// <returns>Retorna um objeto do tipo Classes.Assinatura.Signature, contendo a assinatura do objeto passado como parâmetro</returns> public static Signature ObterAssinatura <T>(T objeto, string id, X509Certificate2 certificadoDigital, bool manterDadosEmCache = false, string signatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1", string digestMethod = "http://www.w3.org/2000/09/xmldsig#sha1", bool cfgServicoRemoverAcentos = false) where T : class { var objetoLocal = objeto; if (id == null) { throw new Exception("Não é possível assinar um objeto evento sem sua respectiva Id!"); } try { var documento = new XmlDocument { PreserveWhitespace = true }; documento.LoadXml(cfgServicoRemoverAcentos ? FuncoesXml.ClasseParaXmlString(objetoLocal).RemoverAcentos() : FuncoesXml.ClasseParaXmlString(objetoLocal)); var docXml = new SignedXml(documento) { SigningKey = certificadoDigital.PrivateKey }; docXml.SignedInfo.SignatureMethod = signatureMethod; var reference = new Reference { Uri = "#" + id, DigestMethod = digestMethod }; // adicionando EnvelopedSignatureTransform a referencia var envelopedSigntature = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelopedSigntature); var c14Transform = new XmlDsigC14NTransform(); reference.AddTransform(c14Transform); docXml.AddReference(reference); // carrega o certificado em KeyInfoX509Data para adicionar a KeyInfo var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificadoDigital)); docXml.KeyInfo = keyInfo; docXml.ComputeSignature(); //// recuperando a representação do XML assinado var xmlDigitalSignature = docXml.GetXml(); var assinatura = FuncoesXml.XmlStringParaClasse <Signature>(xmlDigitalSignature.OuterXml); return(assinatura); } finally { //Marcos Gerene 04/08/2018 - o objeto certificadoDigital nunca será nulo, porque se ele for nulo nem as configs para criar ele teria. //Se não mantém os dados do certificado em cache libera o certificado, chamando o método reset. //if (!manterDadosEmCache & certificadoDigital == null) // certificadoDigital.Reset(); } }
/// <summary> /// Signs a XML file (enveloping signature) using a digital certificate /// </summary> /// <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(byte[] xml, string certFile, string certPassword, bool signWithSha256) { 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); // craete 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> /// Assina o XML utilizando um certificado digital. /// </summary> /// <param name="documentoXML">XML a ser assinado.</param> /// <param name="certificadoX509">Certificado digital a ser utilizado para a assinatura.</param> /// <param name="tagAAssinar">Tag a assinar.</param> /// <param name="idAtributoTag">Atributo ID da tag a assinar.</param> /// <returns></returns> private XmlDocument AssinarXML(XmlDocument documentoXML, X509Certificate2 certificadoX509, TipoEvento tagAAssinar, string idAtributoTag) { // Variáveis utilizadas na assinatura XmlNodeList nodeParaAssinatura = null; SignedXml signedXml = null; Reference reference = null; KeyInfo keyInfo = null; XmlElement sig = null; XmlDocument xmlAssinado = null; bool eValido = true; if (eValido) { // Verifica se o certificado passado por parâmetro possui chave privada. Lembrando que o webservice // da Receita Federal não irá aceitar o certificado caso não possua esta chave. // Até então não foi encontrada uma solução para buscar a chave privada em sistemas web, // porém, funciona normalmente em sistemas desktop. // Segundo pesquisas, esta é uma medida de segurança. if (certificadoX509.HasPrivateKey) { if (!tagAAssinar.Equals(string.Empty)) { if (!idAtributoTag.Equals(string.Empty)) { try { // Informando qual a tag será assinada nodeParaAssinatura = documentoXML.GetElementsByTagName(tagAAssinar.Tag); signedXml = new SignedXml((XmlElement)nodeParaAssinatura[0]); signedXml.SignedInfo.SignatureMethod = signatureMethod; RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)certificadoX509.PrivateKey; if (!privateKey.CspKeyContainerInfo.HardwareDevice) { CspKeyContainerInfo enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo; CspParameters cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, privateKey.CspKeyContainerInfo.KeyContainerName); if (privateKey.CspKeyContainerInfo.MachineKeyStore) { cspparams.Flags |= CspProviderFlags.UseMachineKeyStore; } privateKey = new RSACryptoServiceProvider(cspparams); } // Adicionando a chave privada para assinar o documento signedXml.SigningKey = privateKey; // Referenciando o identificador da tag que será assinada reference = new Reference("#" + nodeParaAssinatura[0].Attributes[idAtributoTag].Value); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform(false)); reference.AddTransform(new XmlDsigC14NTransform(false)); reference.DigestMethod = digestMethod; // Adicionando a referencia de qual tag será assinada signedXml.AddReference(reference); // Adicionando informações do certificado na assinatura keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificadoX509)); signedXml.KeyInfo = keyInfo; // Calculando a assinatura signedXml.ComputeSignature(); // Adicionando a tag de assinatura ao documento xml sig = signedXml.GetXml(); documentoXML.GetElementsByTagName(tagAAssinar.Tag)[0].ParentNode.AppendChild(sig); xmlAssinado = new XmlDocument(); xmlAssinado.PreserveWhitespace = true; xmlAssinado.LoadXml(documentoXML.OuterXml); } catch (Exception ex) { // Falha ao assinar documento XML MessageBox.Show("Falha ao assinar documento XML. " + ex.Message); } } else { MessageBox.Show("String que informa o id da tag XML a ser assinada está vazia"); } } else { MessageBox.Show("String que informa a tag XML a ser assinada está vazia"); } } else { MessageBox.Show("Certificado Digital informado não possui chave privada"); } } return(xmlAssinado); }
// Sign an XML file.This document cannot be verified unless the verifying code has the key with which it was signed. public static void SignXml(XmlDocument doc, RSA key) { // Create a SignedXml object SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document signedXml.KeyInfo = new KeyInfo(); signedXml.KeyInfo.AddClause(new RSAKeyValue(key)); signedXml.SigningKey = key; // Create a reference to be signed Reference reference = new Reference(""); // reference.Uri = ""; // Add an enveloped transformation to the reference XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Set the KeyInfo to the SignedXml object // KeyInfo ki = new KeyInfo(); // ki.AddClause(new RSAKeyValue(key)); // signedXml.SigningKey = key; // signedXml.KeyInfo = ki; // Add the reference to the SignedXml object signedXml.AddReference(reference); // Compute the signature signedXml.ComputeSignature(); // Get the XML representation of the signature and save it to an XmlElement object. // XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document // doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); doc.DocumentElement.PrependChild(signedXml.GetXml()); }
// Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string[] ElementsToSign) { // Check the arguments. if (FileName == null) { throw new ArgumentNullException("FileName"); } if (SignedFileName == null) { throw new ArgumentNullException("SignedFileName"); } if (Key == null) { throw new ArgumentNullException("Key"); } if (ElementsToSign == null) { throw new ArgumentNullException("ElementsToSign"); } // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Loop through each passed element to sign // and create a reference. foreach (string s in ElementsToSign) { // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = s; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); } // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)Key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
/// <summary> /// Assinar digitalmente o XML /// </summary> /// <param name="conteudoXML">XML a ser assinado</param> /// <param name="tagAssinatura">Nome da tag a ser assinada</param> /// <param name="tagAtributoId">Nome da tag que possui o ID para referencia na URI da assinatura</param> /// <param name="x509Cert">Certificado digital a ser utilizado na assinatura</param> /// <param name="algorithmType">Tipo de algorítimo a ser utilizado na assinatura</param> /// <param name="definirURI">Define o Reference.URI na assinatura</param> /// <param name="pinCertificado">PIN do certificado digital, quando do tipo A3</param> /// <param name="idAttributeName">Nome do atributo que tem o ID para assinatura. Se nada for passado o sistema vai tentar buscar o nome Id ou id, se não encontrar, não vai criar a URI Reference na assinatura com ID.</param> public void Assinar(XmlDocument conteudoXML, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, AlgorithmType algorithmType = AlgorithmType.Sha1, bool definirURI = true, string pinCertificado = "", string idAttributeName = "") { try { if (x509Cert == null) { throw new ExceptionCertificadoDigital(); } if (conteudoXML.GetElementsByTagName(tagAssinatura).Count == 0) { throw new Exception("A tag de assinatura " + tagAssinatura.Trim() + " não existe no XML. (Código do Erro: 5)"); } else if (conteudoXML.GetElementsByTagName(tagAtributoId).Count == 0) { throw new Exception("A tag de assinatura " + tagAtributoId.Trim() + " não existe no XML. (Código do Erro: 4)"); } else { XmlNodeList lists = conteudoXML.GetElementsByTagName(tagAssinatura); foreach (XmlNode nodes in lists) { foreach (XmlNode childNodes in nodes.ChildNodes) { if (!childNodes.Name.Equals(tagAtributoId)) { continue; } // Create a reference to be signed Reference reference = new Reference { Uri = "" }; // pega o uri que deve ser assinada XmlElement childElemen = (XmlElement)childNodes; if (definirURI) { if (string.IsNullOrEmpty(idAttributeName)) { if (childElemen.GetAttributeNode("Id") != null) { idAttributeName = "Id"; } else if (childElemen.GetAttributeNode("id") != null) { idAttributeName = "id"; } } else { reference.Uri = "#" + childElemen.GetAttributeNode(idAttributeName).Value; } } SignedXml signedXml = new SignedXml(conteudoXML); if (!string.IsNullOrWhiteSpace(pinCertificado)) { x509Cert.SetPinPrivateKey(pinCertificado); } reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform()); switch (algorithmType) { case AlgorithmType.Sha256: signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SigningKey = x509Cert.GetRSAPrivateKey(); signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; break; default: signedXml.SigningKey = x509Cert.PrivateKey; signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1"; break; } signedXml.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(x509Cert)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); nodes.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } } } } catch (CryptographicException ex) { if (x509Cert.IsA3()) { throw new Exception("O certificado deverá ser reiniciado.\r\n Retire o certificado.\r\nAguarde o LED terminar de piscar.\r\n Recoloque o certificado e informe o PIN novamente.\r\n" + ex.ToString()); } else { throw; } } catch { throw; } }
// Třída podepíše certifikátem dokument XML // Pokud je již dokument podepsaný, přidá se další podpis public XmlDocument Sign(XmlDocument doc, X509Certificate2 cert) { // před podepisováním z dokumentu odstraníme komentáře (.NET s nimi má problémy pokud se kombinují s XPath transformacemi) XmlDocument strippedDoc = RemoveComments(doc); // definice mapování prefixů na jmenné prostory XmlNamespaceManager manager = new XmlNamespaceManager(strippedDoc.NameTable); manager.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#"); // zjištění kolik podpisů již v dokumentu je int signatures = strippedDoc.SelectNodes("//dsig:Signature", manager).Count; // objekt sloužící pro vytvoření podpisu SignedXml signedXml = new SignedXml(strippedDoc); // podepisovat budeme privátním klíčem z certifikátu signedXml.SigningKey = cert.PrivateKey; // podepisovat budeme pomocí RSA-SHA256 signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // reference na podepisovaný dokument ("" znamená celý dokument) Reference reference = new Reference(); reference.Uri = ""; // pro výpočet otisku se bude používat SHA-256 reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // digitální podpis bude přímo součástí dokumentu XML (tzv. "enveloped signature") XmlDsigEnvelopedSignatureTransform envTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envTransform); // navíc budeme používat XPath transoformaci, která dovoluje přidat několik podpisů najednou XmlDsigXPathTransform xpathTransform = new XmlDsigXPathTransform(); // příprava definice XPath transformace jako struktura XML signature XmlDocument transformBody = new XmlDocument(); // podoba XPath filtru se liší podle počtu podpisů if (signatures == 0) transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature)</dsig:XPath>"); else transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature) or not(ancestor-or-self::dsig:Signature/preceding-sibling::dsig:Signature[" + signatures + "])</dsig:XPath>"); // načtení definice XPath transformace do objektu xpathTransform.LoadInnerXml(transformBody.SelectNodes("/*[1]")); // přidání XPath transformace reference.AddTransform(xpathTransform); // přidání reference do podpisu signedXml.AddReference(reference); // přidání certifikátu do podpisu KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; // výpočet podpisu signedXml.ComputeSignature(); // získání XML reprezentace podpisu XmlElement xmlSignature = signedXml.GetXml(); // k podpisu přidáme identifikátor, tak jak doporučuje standard ISDOC xmlSignature.SetAttribute("Id", "Signature-" + (signatures + 1)); // XML dokument pro podepsaný výsledek XmlDocument result = new XmlDocument(); // bílé znaky musíme zachovat, jinak se špatně spočte hash result.PreserveWhitespace = true; // načtení původního dokumentu result.AppendChild(result.ImportNode(strippedDoc.DocumentElement, true)); // připojení podpisu na konec dokumentu XML result.DocumentElement.AppendChild(result.ImportNode(xmlSignature, true)); return result; }