/// <summary> /// O método assina digitalmente o arquivo XML passado por parâmetro e /// grava o XML assinado com o mesmo nome, sobreponto o XML informado por parâmetro. /// Disponibiliza também uma propriedade com uma string do xml assinado (this.vXmlStringAssinado) /// </summary> /// <param name="arqXMLAssinar">Nome do arquivo XML a ser assinado</param> /// <param name="tagAssinatura">Nome da tag onde é para ficar a assinatura</param> /// <param name="tagAtributoId">Nome da tag que tem o atributo ID, tag que vai ser assinada</param> /// <param name="x509Cert">Certificado a ser utilizado na assinatura</param> /// <param name="empresa">Índice da empresa que está solicitando a assinatura</param> /// <remarks> /// Autor: Wandrey Mundin Ferreira /// Data: 04/06/2008 /// </remarks> private void Assinar(string arqXMLAssinar, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, int empresa) { StreamReader SR = null; try { //Abrir o arquivo XML a ser assinado e ler o seu conteúdo SR = File.OpenText(arqXMLAssinar); string xmlString = SR.ReadToEnd(); SR.Close(); SR = null; // 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.LoadXml(xmlString); if (doc.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 (doc.GetElementsByTagName(tagAtributoId).Count == 0) { throw new Exception("A tag de assinatura " + tagAtributoId.Trim() + " não existe no XML. (Código do Erro: 4)"); } // Existe mais de uma tag a ser assinada else { XmlDocument XMLDoc; XmlNodeList lists = doc.GetElementsByTagName(tagAssinatura); XmlNode listRPS = null; /// Esta condição foi feita especificamente para prefeitura de Governador Valadares pois o AtribudoID e o Elemento assinado devem possuir o mesmo nome. /// Talvez tenha que ser reavaliado. #region Governador Valadares if (tagAssinatura.Equals(tagAtributoId) && Empresas.Configuracoes[empresa].UnidadeFederativaCodigo == 3127701) { foreach (XmlNode item in lists) { if (listRPS == null) { listRPS = item; } if (item.Name.Equals(tagAssinatura)) { lists = item.ChildNodes; break; } } } #endregion 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(); reference.Uri = ""; // pega o uri que deve ser assinada XmlElement childElemen = (XmlElement)childNodes; if (childElemen.GetAttributeNode("Id") != null) { reference.Uri = "#" + childElemen.GetAttributeNode("Id").Value; } else if (childElemen.GetAttributeNode("id") != null) { reference.Uri = "#" + childElemen.GetAttributeNode("id").Value; } // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); #if _fw45 //A3 if (!String.IsNullOrEmpty(Empresas.Configuracoes[empresa].CertificadoPIN) && clsX509Certificate2Extension.IsA3(x509Cert) && !Empresas.Configuracoes[empresa].CertificadoPINCarregado) { x509Cert.SetPinPrivateKey(Empresas.Configuracoes[empresa].CertificadoPIN); Empresas.Configuracoes[empresa].CertificadoPINCarregado = true; } #endif signedXml.SigningKey = x509Cert.PrivateKey; // 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(); if (tagAssinatura.Equals(tagAtributoId) && Empresas.Configuracoes[empresa].UnidadeFederativaCodigo == 3127701) { ///Desenvolvido especificamente para prefeitura de governador valadares listRPS.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); } else { // Gravar o elemento no documento XML nodes.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); } } } XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = false; XMLDoc = doc; // Atualizar a string do XML já assinada string StringXMLAssinado = XMLDoc.OuterXml; // Gravar o XML Assinado no HD StreamWriter SW_2 = File.CreateText(arqXMLAssinar); SW_2.Write(StringXMLAssinado); SW_2.Close(); } } catch (System.Security.Cryptography.CryptographicException ex) { #region #10316 /* * Solução para o problema do certificado do tipo A3 * Marcelo * 29/07/2013 */ AssinaturaValida = false; #if DEBUG Debug.WriteLine("O erro CryptographicException foi lançado"); #endif if (clsX509Certificate2Extension.IsA3(x509Cert)) { x509Cert = Empresas.ResetCertificado(empresa); if (!TesteCertificado) { 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());// #12342 concatenar com a mensagem original } } else { throw; } #endregion } catch { throw; } finally { if (SR != null) { SR.Close(); } } }
/// <summary> /// O método assina digitalmente o arquivo XML passado por parâmetro e /// grava o XML assinado com o mesmo nome, sobreponto o XML informado por parâmetro. /// Disponibiliza também uma propriedade com uma string do xml assinado (this.vXmlStringAssinado) /// </summary> /// <param name="conteudoXML">Conteúdo do XML</param> /// <param name="tagAssinatura">Nome da tag onde é para ficar a assinatura</param> /// <param name="tagAtributoId">Nome da tag que tem o atributo ID, tag que vai ser assinada</param> /// <param name="x509Cert">Certificado a ser utilizado na assinatura</param> /// <param name="empresa">Índice da empresa que está solicitando a assinatura</param> /// <param name="algorithmType">Tipo de algoritimo para assinatura do XML.</param> /// <remarks> /// Autor: Wandrey Mundin Ferreira /// Data: 04/06/2008 /// </remarks> private void Assinar(XmlDocument conteudoXML, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, int empresa, AlgorithmType algorithmType, bool comURI) { try { if (x509Cert == null) { throw new ExceptionCertificadoDigital(ErroPadrao.CertificadoNaoEncontrado); } 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)"); } // Existe mais de uma tag a ser assinada else { XmlNodeList lists = conteudoXML.GetElementsByTagName(tagAssinatura); XmlNode listRPS = null; /// Esta condição foi feita especificamente para prefeitura de Governador Valadares pois o AtribudoID e o Elemento assinado devem possuir o mesmo nome. /// Talvez tenha que ser reavaliado. #region Governador Valadares if (tagAssinatura.Equals(tagAtributoId) && Empresas.Configuracoes[empresa].UnidadeFederativaCodigo == 3127701) { foreach (XmlNode item in lists) { if (listRPS == null) { listRPS = item; } if (item.Name.Equals(tagAssinatura)) { lists = item.ChildNodes; break; } } } #endregion Governador Valadares 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(); reference.Uri = ""; // pega o uri que deve ser assinada XmlElement childElemen = (XmlElement)childNodes; if (comURI) { if (childElemen.GetAttributeNode("Id") != null) { reference.Uri = "#" + childElemen.GetAttributeNode("Id").Value; } else if (childElemen.GetAttributeNode("id") != null) { reference.Uri = "#" + childElemen.GetAttributeNode("id").Value; } } // Create a SignedXml object. SignedXml signedXml = new SignedXml(conteudoXML); #if _fw46 //A3 if (!String.IsNullOrEmpty(Empresas.Configuracoes[empresa].CertificadoPIN) && clsX509Certificate2Extension.IsA3(x509Cert) && !Empresas.Configuracoes[empresa].CertificadoPINCarregado) { x509Cert.SetPinPrivateKey(Empresas.Configuracoes[empresa].CertificadoPIN); Empresas.Configuracoes[empresa].CertificadoPINCarregado = true; } if (algorithmType.Equals(AlgorithmType.Sha256)) { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SigningKey = x509Cert.GetRSAPrivateKey(); } #endif if (algorithmType.Equals(AlgorithmType.Sha1)) { 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"; } // Add an enveloped transformation to the reference. reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform()); // Add the reference to the SignedXml object. signedXml.AddReference(reference); #if _fw46 if (algorithmType.Equals(AlgorithmType.Sha256)) { reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; } #endif // 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(); if (tagAssinatura.Equals(tagAtributoId) && Empresas.Configuracoes[empresa].UnidadeFederativaCodigo == 3127701) { ///Desenvolvido especificamente para prefeitura de governador valadares listRPS.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } else { // Gravar o elemento no documento XML nodes.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } } } } } catch (CryptographicException ex) { #region #10316 /* * Solução para o problema do certificado do tipo A3 * Marcelo * 29/07/2013 */ AssinaturaValida = false; if (clsX509Certificate2Extension.IsA3(x509Cert)) { x509Cert = Empresas.ResetCertificado(empresa); if (!TesteCertificado) { 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());// #12342 concatenar com a mensagem original } } else { throw; } #endregion #10316 } catch { throw; } }