Stack Overflow em Português Asked by Lucas Ferreira on January 27, 2021
Tenho um código c# que gera um xml com a assinatura digital, porém ao chamar a função signedXml.ComputeSignature()
ele mostra o seguinte erro:
Elemento Reference mal formado.
Entretanto, eu pesquisei sobre esse erro e maioria dos sites ou fóruns cita a remoção da atualização KB3136000, só que no windows 10 que estou usando não tem essa atualização instalada.
O que pode ser?
Segue o código abaixo com destaque para a linha de erro:
public static void AssinaDocumento(X509Certificate2 certificadoDigital, string Uri, string xmlOrigem)
{
int countTagsUri;
XmlDocument xmlDocument = new XmlDocument();
XmlDocument xmlDocument2 = new XmlDocument();
xmlDocument.PreserveWhitespace = false;
XmlNodeList xmlNodeList;
Reference reference = new Reference();
xmlDocument.Load(xmlOrigem);
xmlDocument2 = xmlDocument;
XmlDocument xmlAssinado = xmlDocument;
SignedXml signedXml = new SignedXml(xmlDocument);
signedXml.SigningKey = certificadoDigital.PrivateKey;
countTagsUri = xmlDocument.GetElementsByTagName(Uri).Count;
if (countTagsUri == 0)
{
throw new Exception("Uri " + Uri + " não encontrada no XML");
}
xmlNodeList = xmlDocument.GetElementsByTagName(Uri);
foreach (XmlNode xmlnl in xmlNodeList)
{
XmlAttributeCollection attributeCollection = xmlnl.FirstChild.Attributes;
reference.Uri = "#" + attributeCollection["id"].InnerText;
string res = xmlnl.OuterXml;
XmlDsigEnvelopedSignatureTransform envelope = new XmlDsigEnvelopedSignatureTransform();
XmlDsigC14NTransform c14NTransform = new XmlDsigC14NTransform();
KeyInfo keyInfo = new KeyInfo();
reference.AddTransform(envelope);
reference.AddTransform(c14NTransform);
signedXml.AddReference(reference);
keyInfo.AddClause(new KeyInfoX509Data(certificadoDigital));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature(); // O erro Ocorre aqui
XmlElement xmlDigitalSignature = signedXml.GetXml();
XmlNode xmlNode = xmlDocument.ImportNode(xmlDigitalSignature, true);
xmlDocument.FirstChild.NextSibling.LastChild.InsertAfter(xmlNode, xmlnl.LastChild);
xmlDocument.PreserveWhitespace = true;
xmlDocument.Save(@"C:Userster0038Desktopassinado.xml");
}
}
Olá, Com a desativação do Win7 e todos migrarem para o Win10 então você deve COMEÇAR o Id com letra e não com número. (Isso acontece muito com o pessoal que implementa NFSe para prefeituras). Digo isso, pelo fato de alguns developers indicarem a Remoção de algumas atualizações do Win7 Exemplo:
(ERRADO)
<EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd">
<LoteRps id="002">
</EnviarLoteRpsEnvio>
(CERTO)
<EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd">
<LoteRps id="A002">, onde A pode ser qualquer letra não especial
</EnviarLoteRpsEnvio>
Answered by Marinpietri on January 27, 2021
Tenta com este código:
private XmlDocument AssinarXml(string arquivo, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert)
{
StreamReader SR = null;
try
{
SR = File.OpenText(arquivo);
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)");
}
else
{
XmlDocument XMLDoc;
XmlNodeList lists = doc.GetElementsByTagName(tagAssinatura);
foreach (XmlNode nodes in lists)
{
foreach (XmlNode childNodes in nodes.ChildNodes)
{
if (!childNodes.Name.Equals(tagAtributoId))
continue;
if (childNodes.NextSibling != null && childNodes.NextSibling.Name.Equals("Signature"))
continue;
// Create a reference to be signed
Reference reference = new Reference();
reference.Uri = "";
XmlElement childElemen = (XmlElement)childNodes;
if (childElemen.GetAttributeNode("Id") != null)
{
//reference.Uri = ""; // "#" + childElemen.GetAttributeNode("Id").Value;
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);
// Add the key to the SignedXml document
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();
nodes.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
}
}
XMLDoc = new XmlDocument();
XMLDoc.PreserveWhitespace = false;
XMLDoc = doc;
return XMLDoc;
//string conteudoXMLAssinado = XMLDoc.OuterXml;
//using (StreamWriter sw = File.CreateText(arquivo))
//{
// sw.Write(conteudoXMLAssinado);
// sw.Close();
//}
}
}
finally
{
if (SR != null)
SR.Close();
}
}
Answered by Matheus Rizzi on January 27, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP