0
I’m trying to sign the data block of the Gerarnfse method.
It is necessary to sign the RPS and the batch. However, when sending, I always get the invalid signature message.
Follow the code I’m using:
public static void AssinarNFSe(XmlDocument doc, X509Certificate2 certificado)
{
XmlNodeList ListInfRps = doc.GetElementsByTagName("InfRps");
int NodeCounter = 1;
foreach (XmlElement InfRps in ListInfRps)
{
string idRPS = InfRps.Attributes.GetNamedItem("Id").Value;
SignedXml signedXmlRps = new SignedXml(InfRps);
signedXmlRps.SigningKey = certificado.PrivateKey;
Reference referenceRps = new Reference("#" + idRPS);
referenceRps.AddTransform(new XmlDsigEnvelopedSignatureTransform());
referenceRps.AddTransform(new XmlDsigC14NTransform());
signedXmlRps.AddReference(referenceRps);
KeyInfo keyInfoRps = new KeyInfo();
keyInfoRps.AddClause(new KeyInfoX509Data(certificado));
signedXmlRps.KeyInfo = keyInfoRps;
signedXmlRps.ComputeSignature();
XmlElement xmlSignatureRps = doc.CreateElement("Signature", "http://www.w3.org/2000/09/xmldsig#");
XmlAttribute attrRps = doc.CreateAttribute("Id");
attrRps.Value = "Ass_" + idRPS;
xmlSignatureRps.Attributes.SetNamedItem(attrRps);
XmlElement xmlSignedInfoRps = signedXmlRps.SignedInfo.GetXml();
XmlElement xmlKeyInfoRps = signedXmlRps.KeyInfo.GetXml();
XmlElement xmlSignatureValueRps = doc.CreateElement("SignatureValue", xmlSignatureRps.NamespaceURI);
string signBase64Rps = Convert.ToBase64String(signedXmlRps.Signature.SignatureValue);
XmlText textRps = doc.CreateTextNode(signBase64Rps);
xmlSignatureValueRps.AppendChild(textRps);
xmlSignatureRps.AppendChild(doc.ImportNode(xmlSignedInfoRps, true));
xmlSignatureRps.AppendChild(xmlSignatureValueRps);
xmlSignatureRps.AppendChild(doc.ImportNode(xmlKeyInfoRps, true));
XmlNodeList ListRps = doc.GetElementsByTagName("Rps");
int RpsCounter = 1;
foreach (XmlElement Rps in ListRps)
{
if (RpsCounter == NodeCounter)
{
Rps.AppendChild(xmlSignatureRps);
}
RpsCounter++;
}
NodeCounter++;
}
XmlNodeList ListLoteRps = doc.GetElementsByTagName("LoteRps");
foreach (XmlElement LoteRps in ListLoteRps)
{
string id = LoteRps.Attributes.GetNamedItem("Id").Value;
SignedXml signedXml = new SignedXml(LoteRps);
signedXml.SigningKey = certificado.PrivateKey;
Reference reference = new Reference("#" + id);
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigC14NTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificado));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement xmlSignature = doc.CreateElement("Signature", "http://www.w3.org/2000/09/xmldsig#");
XmlAttribute attr = doc.CreateAttribute("Id");
attr.Value = "Ass_" + id;
xmlSignature.Attributes.SetNamedItem(attr);
XmlElement xmlSignedInfo = signedXml.SignedInfo.GetXml();
XmlElement xmlKeyInfo = signedXml.KeyInfo.GetXml();
XmlElement xmlSignatureValue = doc.CreateElement("SignatureValue", xmlSignature.NamespaceURI);
string signBase64 = Convert.ToBase64String(signedXml.Signature.SignatureValue);
XmlText text = doc.CreateTextNode(signBase64);
xmlSignatureValue.AppendChild(text);
xmlSignature.AppendChild(doc.ImportNode(xmlSignedInfo, true));
xmlSignature.AppendChild(xmlSignatureValue);
xmlSignature.AppendChild(doc.ImportNode(xmlKeyInfo, true));
XmlNodeList ListEnviarLoteRpsEnvio = doc.GetElementsByTagName("GerarNfseEnvio");
foreach (XmlElement EnviarLoteRpsEnvio in ListEnviarLoteRpsEnvio)
{
EnviarLoteRpsEnvio.AppendChild(xmlSignature);
}
}
}
And what makes you think it’s correct? You checked the generated XML and compared it with the documentation?
– Leandro Angelo