Página 1 de 2

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 14:22
por malcarli
Achei esta rotina em c#, seria possível converter em c para ser usado no harbour?

Código: Selecionar todos

class Assinatura
{
    public string AssinarSHA256(Int32 lnEvento, 
        string arqXMLAssinar,
        string tagAssinatura,
        string tagAtributoId,
        X509Certificate2 x509Cert,
        string lxURI)
    {
        try
        {
            string xmlString;
            xmlString = arqXMLAssinar;

            XmlDocument doc = new XmlDocument();
            // Format the document to ignore white spaces.
            doc.PreserveWhitespace = false;

            doc.LoadXml(xmlString);

            XmlElement xmlDigitalSignature = null;

            // Load the passed XML file using it’s name.

            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
            {
                XmlNodeList lists = doc.GetElementsByTagName(tagAssinatura);

                if (lists.Count != 1)
                {
                    MessageBox.Show("Existe mais de uma TAG definida como tag da assinatura");
                    throw new Exception("Existe mais de uma tag de assinatura " + tagAtributoId.Trim() + " não existe no XML. (Código do Erro: 6)");
                }

                #region 
                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 = lxURI;

                        // Create a SignedXml object.
                        SignedXml signedXml = new SignedXml(doc);

                        signedXml.SigningKey = x509Cert.GetRSAPrivateKey();

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

                        // Add an enveloped transformation to the reference.
                        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

                        reference.AddTransform(env);

                        XmlDsigC14NTransform c14 = new XmlDsigC14NTransform();

                        reference.AddTransform(c14);

                        reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";


                        // 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.
                        xmlDigitalSignature = signedXml.GetXml();

                        // Gravar o elemento no documento XML
                        nodes.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

                    }
                }

                #endregion



                // Atualizar a string do XML já assinada
                return doc.OuterXml;
            }
        }
        catch (System.Security.Cryptography.CryptographicException ex)
        {

            throw new Exception("Mensagem:" + ex.Message + "\n" +
                "Trace:" + ex.StackTrace + "\n" +
                "Dados" + ex.Data + "\n" +
                ex.ToString());// #12342 concatenar com a mensagem original
        }
        finally
        {

        }
    }
}

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 14:38
por Itamar M. Lins Jr.
Olá!
Nos fontes do ACBr você pode encontrar algo.
Eu procurei, mas não entendo como é, parece que não faz nada só fica adicionando tags no XML.
Eu pegaria um NFSe que está ok e tentaria fazer igual.

Código: Selecionar todos

itamar@itamar-desktop:~/dev/acbr/Fontes/ACBrDFe$ grep "assina" *.pas
ACBrDFeSSL.pas:    // Verificando se modificou o Header do XML assinado, e voltando para o anterior //
grep: ACBrDFeSSL.pas: binary file matches
ACBrDFeWebService.pas:     para assinatura.
grep: ACBrDFeWebService.pas: binary file matches
ACBrDFeWinCrypt.pas:            // MS CryptoAPI retorna assinatura em "Little Endian bit string", invertendo...
ACBrDFeXsLibXml2.pas:    // Caso a URI Seja vazia precisa calcular o hash para o documento todo sem a tag assinatura.
ACBrDFeXsLibXml2.pas:    assinatura, relacionado a ele (mesmo pai) }
ACBrDFeXsLibXml2.pas:      { Vamos achar o pai desse Elemento, pois com ele encontraremos a assinatura no final }
grep: ACBrDFeXsLibXml2.pas: binary file matches
ACBrDFeXsMsXmlCapicom.pas:      // Criando Elemento de assinatura //
grep: ACBrDFeXsMsXmlCapicom.pas: binary file matches
ACBrDFeXsMsXml.pas:      // Criando Elemento de assinatura //
ACBrDFeXsMsXml.pas:          MsgErro := 'Erro ao verificar assinatura do arquivo: ' + E.Message;
ACBrDFeXsXmlSec.pas:  cErrDSigSign = 'Erro %d: Falha ao assinar o Documento';
ACBrDFeXsXmlSec.pas:    assinatura, relacionado a ele (mesmo pai) }
ACBrDFeXsXmlSec.pas:      { Vamos achar o pai desse Elemento, pois com ele encontraremos a assinatura no final }
grep: ACBrDFeXsXmlSec.pas: binary file matches
itamar@itamar-desktop:~/dev/acbr/Fontes/ACBrDFe$ kate ACBrDFeXsMsXml.pas 
Saudações,
Itamar M. Lins Jr.

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 20:27
por JoséQuintas
A rotina C# tá bem parecida com a da SEFAZCLASS, não estão enxergando não?

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 20:57
por JoséQuintas
primeiro no VB6 com early binding....

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 21:06
por JoséQuintas
Isso sim é uma IDE, que não tem pra HARBOUR.

primeiro acrescenta referência a XML5
t1.png
t2.png
Depois começa a declarar variável, o VB6 já complementa
t3.png
e vai continuando com o fonte, e o VB6 complementando
t4.png
t5.png
t6.png
t7.png

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 21:11
por JoséQuintas
Então........ early binding é o programa já conhecer o uso, igual LIBs que criam pra Harbour, que dependem da DLL.

late binding, é poder conhecer o que vai usar depois....

Código: Selecionar todos

DomDoc = CreateObject( "... " )
Que no Harbour é

Código: Selecionar todos

DomDoc := win_OleCreateObject( ... )
O restante segue igual.

Legal né?

VB6 é do tempo do Windows 98.... 24 anos atrás...

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 21:13
por JoséQuintas
Voltando ao fonte em C#

Código: Selecionar todos

            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = false;
            doc.LoadXml(xmlString);
t7.png
Equivalente no Harbour, precisa procurar o nome correto:

Código: Selecionar todos

Doc := win_OleCreateObject( "DomDocument" ) // precisa usar o nome correto
Doc:PreserveWhiteSpace := .F.
Doc:LoadXml( "nome.xml" )

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 21:23
por JoséQuintas
Isto:

Código: Selecionar todos

 // Create a reference to be signed
                        Reference reference = new Reference();

                        reference.Uri = lxURI;

                        // Create a SignedXml object.
                        SignedXml signedXml = new SignedXml(doc);

                        signedXml.SigningKey = x509Cert.GetRSAPrivateKey();

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

                        // Add an enveloped transformation to the reference.
                        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

                        reference.AddTransform(env);

                        XmlDsigC14NTransform c14 = new XmlDsigC14NTransform();

                        reference.AddTransform(c14);

                        reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";

                        // Add the reference to the SignedXml object.
                        signedXml.AddReference(reference);
tudo indica que seja isto:

Código: Selecionar todos

STATIC FUNCTION AssinaBlocoAssinatura( cURI, lComURI )

   LOCAL cSignatureNode := ""

   IF lComURI
      cURI := "#" + cURI
   ENDIF
   cSignatureNode += [<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">]
   cSignatureNode +=    [<SignedInfo>]
   cSignatureNode +=       [<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>]
   cSignatureNode +=       [<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />]
   cSignatureNode +=       [<Reference URI="] + cURI + [">]
   cSignatureNode +=       [<Transforms>]
   cSignatureNode +=          [<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />]
   cSignatureNode +=          [<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />]
   cSignatureNode +=       [</Transforms>]
   cSignatureNode +=       [<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />]
   cSignatureNode +=       [<DigestValue>]
   cSignatureNode +=       [</DigestValue>]
   cSignatureNode +=       [</Reference>]
   cSignatureNode +=    [</SignedInfo>]
   cSignatureNode +=    [<SignatureValue>]
   cSignatureNode +=    [</SignatureValue>]
   cSignatureNode +=    [<KeyInfo>]
   cSignatureNode +=    [</KeyInfo>]
   cSignatureNode += [</Signature>]

   RETURN cSignatureNode
Com os devidos ajustes, é claro

Converter de c# para c - Assinar sha256

Enviado: 07 Set 2022 21:35
por JoséQuintas
Lembrando que isso veio da HBNFE, se não fosse ela eu não saberia assinar.

Em ze_sefazassina.prg

Código: Selecionar todos

STATIC FUNCTION AssinaLoadXml( oDomDocument, cTxtXml, cRetorno )

   LOCAL lOk := .F.

   BEGIN SEQUENCE WITH __BreakBlock()

#ifdef __XHARBOUR__
      oDOMDocument := xhb_CreateObject( "MSXML2.DOMDocument.5.0" )
#else
      oDOMDocument := win_OleCreateObject( "MSXML2.DOMDocument.5.0" )
#endif
      oDOMDocument:async              := .F.
      oDOMDocument:resolveExternals   := .F.
      oDOMDocument:validateOnParse    := .T.
      oDOMDocument:preserveWhiteSpace := .T.
      lOk := .T.
Então.... é ajustar o bloco de assinatura com a informação de como será assinado e assinar.

E o principal: TORCER para que a CAPICOM reconheça um tipo de assinatura que não existia na época do lançamento dela, mas que pode ter sido acrescentada depois numa atualização.

Senão.... é apelar pra alguma coisa em NET, afinal, C# faz uso do NET Framework.

E aí vém a parte cômica:
No Windows está disponível pra qualquer linguagem de programação NET grátis, mas para o Harbour, talvez tenha que comprar alguma coisa.
Mesmo existindo assinatura sha256 dentro do Harbour, fazer o quê?

Converter de c# para c - Assinar sha256

Enviado: 08 Set 2022 09:00
por malcarli
Legal, Mestre que aula, mas só salientando, nfe, etc usa sha1 que está devidamente implementada na sua classe, sha256 usa para o esocial. Mesmo pais, situçãos diferentes. O que realmente preciso é funcionar a bendida sha256. obrigado
Mesmo existindo assinatura sha256 dentro do Harbour, fazer o quê?
Onde tem, não seria a solução para adaptar a classe da nfe que assina com sha1 para aceitar tb sha256 para o esocial?

Converter de c# para c - Assinar sha256

Enviado: 08 Set 2022 11:26
por malcarli
aqui inclui os evtCAT, evtMonit, evtExpRisco que são os eventos que vou usar (mas não sei se está certo pois esocial posso enviar até 50 eventos por lote)

Código: Selecionar todos

STATIC FUNCTION AssinaAjustaInformacao( cTxtXml, cXmlTagInicial, cXmlTagFinal, cRetorno, lComURI )

   LOCAL aDelimitadores, nPos, nPosIni, nPosFim, cURI

   aDelimitadores := { ;
      { "<enviMDFe",              "</MDFe></enviMDFe>" }, ;
      { "<eventoMDFe",            "</eventoMDFe>" }, ;
      { "<eventoCTe",             "</eventoCTe>" }, ;
      { "<infMDFe",               "</MDFe>" }, ;
      { "<infCte",                "</CTe>" }, ;
      { "<infNFe",                "</NFe>" }, ;
      { "<infDPEC",               "</envDPEC>" }, ;
      { "<infInut",               "<inutNFe>" }, ;
      { "<infCanc",               "</cancNFe>" }, ;
      { "<infInut",               "</inutNFe>" }, ;
      { "<infInut",               "</inutCTe>" }, ;
      { "<infEvento",             "</evento>" }, ;
      { "<evtInfoEmpregador",     "</eSocial>" }, ;
      { "<evtCAT",                "</eSocial>" }, ;
      { "<evtMonit",              "</eSocial>" }, ;
      { "<evtExpRisco",           "</eSocial>" }, ;
      { "<PedidoEnvioLoteRPS",    "</RPS>" }, ;
      { "<PedidoEnvioRPS",        "</RPS>" }, ;
      { "<infPedidoCancelamento", "</Pedido>" }, ;               // NFSE ABRASF Cancelamento
      { "<LoteRps",               "</EnviarLoteRpsEnvio>" }, ;   // NFSE ABRASF Lote
      { "<infRps",                "</Rps>" } }                   // NFSE ABRASF RPS
Aqui alterei para aceitar o escopo para assinatura do sha256, mas o ideal se for implementar na classe seria introduzir uma variavel para definar a diferenciação

Código: Selecionar todos

STATIC FUNCTION AssinaBlocoAssinatura( cURI, lComURI )

   LOCAL cSignatureNode := ""

   IF lComURI
      cURI := "#" + cURI
   ENDIF
   cSignatureNode += [<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">]
   cSignatureNode +=    [<SignedInfo>]
   cSignatureNode +=       [<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />]
   cSignatureNode +=       [<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />]
   cSignatureNode +=       [<Reference URI="] + cURI + [">]
   cSignatureNode +=       [<Transforms>]
   cSignatureNode +=          [<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />]
   cSignatureNode +=          [<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />]
   cSignatureNode +=       [</Transforms>]
   cSignatureNode +=       [<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />]
   cSignatureNode +=       [<DigestValue>]
   cSignatureNode +=       [</DigestValue>]
   cSignatureNode +=       [</Reference>]
   cSignatureNode +=    [</SignedInfo>]
   cSignatureNode +=    [<SignatureValue>]
   cSignatureNode +=    [</SignatureValue>]
   cSignatureNode +=    [<KeyInfo>]
   cSignatureNode +=    [</KeyInfo>]
   cSignatureNode += [</Signature>]
RETURN cSignatureNode

Converter de c# para c - Assinar sha256

Enviado: 08 Set 2022 11:48
por JoséQuintas
http://suporte.quarta.com.br/eSocial/AssinaturaXml.htm

Uma coisa é pra NFE, outra coisa é pra ESocial.
Não dá pra sair alterando sem saber se funciona.
Além disso, pode ser que o hash seja SHA256 mas a assinatura SHA1, sei lá o que inventam.

Converter de c# para c - Assinar sha256

Enviado: 08 Set 2022 13:16
por malcarli
O colega Itamar mandou esse link, que tem sha256 também e funciona com harbour

https://groups.google.com/g/harbour-use ... pFwjQQBgAJ

Converter de c# para c - Assinar sha256

Enviado: 08 Set 2022 19:12
por JoséQuintas
malcarli escreveu:O colega Itamar mandou esse link, que tem sha256 também e funciona com harbour
Testou? compila e funciona?

Converter de c# para c - Assinar sha256

Enviado: 12 Set 2022 07:01
por malcarli
compilou, mas estou tentanto entender como usar para assinar