How to sign NF-e XML in ASP.NET Core using NF-e 4.00 signature standards?

Asked

Viewed 862 times

1

I am developing an API with ASP.NET Core, communicating with Sefaz to send NF-and, however I am having a problem signing XML, below is the code that makes the signature:

var listas = xmlAssinar.GetElementsByTagName(infosTipoOperacao.TagAssinatura);

foreach (XmlNode nodes in listas)
{
    foreach (XmlNode childNodes in nodes.ChildNodes)
    {
        if (!childNodes.Name.Equals(infosTipoOperacao.TagAtributoId))
        {
            continue;
        }

        // Cria uma referência para ser assinado
        var reference = new Reference
        {
            DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1",
            Uri = string.Empty
        };

        // Pega o uri que deve ser assinada                                       
        var childElemen = (XmlElement)childNodes;

        if (childElemen.GetAttributeNode("Id") != null)
        {
            reference.Uri = string.Format("#{0}", childElemen.GetAttributeNode("Id").Value);
        }
        else if (childElemen.GetAttributeNode("id") != null)
        {
            reference.Uri = string.Format("#{0}", childElemen.GetAttributeNode("id").Value);
        }

        // Cria um objeto SignedXml
        var signedXml = new SignedXml(xmlAssinar)
        {                            
            // Adicione a chave ao documento SignedXml
            SigningKey = certificadoDigital.PrivateKey
        };

        // Adiciona uma transformação envelopada à referência
        var env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

        var c14 = new XmlDsigC14NTransform();
        reference.AddTransform(c14);

        // Adiciona a referência ao objeto SignedXml
        signedXml.AddReference(reference);

        // Cria um novo objeto KeyInfo
        var keyInfo = new KeyInfo();

        // Carrega o certificado em um objeto KeyInfoX509Data e adicione-o ao objeto KeyInfo
        keyInfo.AddClause(new KeyInfoX509Data(certificadoDigital));

        // Adiciona o objeto KeyInfo ao objeto SignedXml
        signedXml.KeyInfo = keyInfo;
        signedXml.ComputeSignature();

        // Obtém a representação XML da assinatura e salve-a em um objeto XmlElement
        var xmlDigitalSignature = signedXml.GetXml();

        // Grava o elemento no documento XML
        nodes.AppendChild(xmlAssinar.ImportNode(xmlDigitalSignature, true));
    }
}

xmlAssinar.PreserveWhitespace = false;

return xmlAssinar;

This code I also use in ASP.NET Framework and works normally, but when using Core, in the validation of Nfe returns me the following error:

The value of the 'Algorithm' attribute does not Equal its Fixed value

or

The value of the 'Algorithm' attribute is not equal to its fixed value

It was then that I realized that inside the object PrivateKey in the Digital Certificate has a different return from the return of the Framework and I believe this is affecting the signature algorithm.

  • What type of object is returned by the property certificadoDigital.PrivateKey? Have you tried using the extension method certificadoDigital.GetRSAPrivateKey()?

1 answer

0

It seems that failed to inform the algorithm (SHA1) that should be used for the signature, with the following line:

signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha1";

You have indicated the SHA1 through the property Reference.DigestMethod, but it’s the property SignedInfo.SignatureMethod which defines which algorithm will be used for the signature.

Here’s an example with SHA256, but you can get an idea:

EFD-Reinf: Signature Error - A Xmldocument Context is Required for Enveloped Transformations

Browser other questions tagged

You are not signed in. Login or sign up in order to post.