/// <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> public void Assinar(XmlDocument conteudoXML, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, AlgorithmType algorithmType = AlgorithmType.Sha1, bool definirURI = true, string pinCertificado = "") { 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 (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); //Para certificado A3, vamos carregar o PIN para não ficar solicitando. if (!string.IsNullOrWhiteSpace(pinCertificado)) { x509Cert.SetPinPrivateKey(pinCertificado); } if (algorithmType.Equals(AlgorithmType.Sha256)) { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SigningKey = x509Cert.GetRSAPrivateKey(); } if (algorithmType.Equals(AlgorithmType.Sha1)) { signedXml.SigningKey = x509Cert.PrivateKey; } // 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 (algorithmType.Equals(AlgorithmType.Sha256)) { reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; } // 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(); // Gravar o elemento no documento XML 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());// #12342 concatenar com a mensagem original } else { throw; } } catch { throw; } }
private void Assina(XmlDocument conteudoXML, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, 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; 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; } // 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(); // Gravar o elemento no documento XML nodes.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } } } } catch { throw; } }
/// <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; } }