- 13.1. Assinatura XML
13.1.3. Assinar NFC-e 4.00 [06-05-18] - 13.1.2. Assinar NFC-e [07-10-15]
« Anterior - 13.1.4. Validar Assinatura
Próximo »
13.1.3. Assinar NFC-e 4.00 [06-05-18]
Assinatura Digital XML da NFC-e no padrão do Projeto NF-e
Assinatura
string AssinarNFCE400(string NFCe, string NomeCertificado,string idToken, string CSC, string versaoQRCode, string URLConsulta, string urlChave, string indSinc,out int resultado, out string msgResultado, out string lote, out string urlNFCe)
Descrição:
Funcionalidade para realizar a assinatura digital no padrão XML Digital Signature enveloped em uma NFC-e e inclusão da URL do QRCode no XML assinado.
É necessário informar o certificado digital que será utilizado para assinatura no parâmetro NomeCertificado.
A DLL oferece 3 forma de uso do certificado digital:
1. uso de certificado digital existente no repositório MY do CSP do usuário corrente (currentuser)
É a forma de mais comum de uso, cabe ressaltar que é a única forma de uso de certificado digital do tipo A3 que a DLL oferece.
O usuário deve passar como parâmetro o campo assunto do certificado no parâmetro NomeCertificado para que a DLL localize um certificado digital com mesmo assunto no repositório MY do currentuser do equipamento.
Esta forma de uso requer a prévia instalação do certificado digital na conta do usuário do Windows (logon) que irá utilizar o certificado digital.
2. uso de certificado digital em arquivo no formato pfx
Permite o de uso de certificado digital em arquivo formato pfx.
O caminho da localização (path) do arquivo pfx deve ser passado para a DLL no formato: ARQUIVO | [nome do arquivo pfx com caminho completo] | [senha do arquivo] no parâmetro NomeCertificado, ex.: "ARQUIVO|c:\certificado.pfx|senha".
Esta opção só funciona com certificado digital do tipo A1.
3. uso de certificado digital em string base64
Permite uso o arquivo do certificado digital em formato pfx convertido em uma string base64. O certificado digital em string base64 deve ser passado para a DLL no formato: CERTIFICADO | [string base64 do arquivo pfx] | [senha do arquivo] no parâmetro NomeCertificado, ex.: "CERTIFICADO|MIIGoDCCBYigAwIBAgIQep(arquivo pfx do certificado digital convertido em base64...)QQDExNBQy|senha".
Esta opção só funciona com certificado digital do tipo A1. É uma opção de uso que oferece maior versatilidade, pois permite o armazenamento do certificado digital em banco de dados na aplicação. É a forma mais indicada para uso em ASP.NET.
Validade do Certificado Digital
A DLL só trabalha com certificados digitais que estão dentro do período de validade. Assim, os certificados digitais que não se encontram dentro do período de validade não serão utilizados. Algumas AC emitem certificados digitais com data de início de validade futura, neste caso o certificado digital só vai ser mostrado a partir da data e hora que constar como data de início de validade, da mesma forma os certificados digitais expirados não serão mostrados.
Repositório de Certificado Digital
A DLL pesquisa o repositório de certificados digitais do usuário corrente, isto é, somente os certificados digitais instalados no repositório de certificados digitais do logon do usuário estarão disponíveis. Caso a aplicação seja um serviço windows ou seja executada como um serviço (aplicação ASP), pode ser necessária a instalação do certificado digital no repositório local machine e uma versão diferente da DLL.
Certificado Digital com chave privada
Quando falamos de certificado digital válido, estamos falando de um certificado digital com chave privada. Já aconteceu do desenvolvedor receber o certificado digital do cliente, que mesmo após a instalação não aparecia no repositório de certificados digitais por não possuir a chave privada. A chave pública do certificado digital não tem a chave privada e geralmente tem a extensão cer, assim caso receba um arquivo com esta extensão, existe uma grande possibilidade de ser uma chave pública que não serve para autenticar e nem para assinatura digital.
Também é possível verificar se o certificado digital tem chave privada ou não pela sua propriedade na opção Ferramentas/Opções da Internet/Conteúdo/Certificados/Exibir do menu do Internet Explorer:
Parâmetros:
nome | tipo | fluxo | descrição |
---|---|---|---|
NFCe | string | entrada | informar uma string com o XML da NFC-e que será assinado. |
NomeCertificado | string | entrada | informar o certificado digital que será utilizado para assinatura: 1. informar o assunto do certificado digital que deve existir no repositório MY do current user, ex.: "CN=NFe - Associacao NF-e:99999090910270, C=BR, L=PORTO ALEGRE, O=Teste Projeto NFe RS, OU=Teste Projeto NFe RS, S=RS". 2. informar: ARQUIVO | [nome do arquivo pfx com caminho completo] | [senha do arquivo] para uso do certificado digital em arquivo pfx, ex.: "ARQUIVO|c:\certificado.pfx|senha". 3. informar: CERTIFICADO | [string base64 do arquivo pfx] | [senha do arquivo] no parâmetro NomeCertificado para passar uma string contendo um certificado digital em base64, ex.:"CERTIFICADO|MIIGoDCCBYigAwIBAgIQep(arquivo pfx do certificado digital convertido em base64...)QQDExNBQy|senha". |
idToken | string | entrada | informar o idToken com 6 dígitos, exemplo "000001" para a versão 3.10. Para a versão 4.00 do leiaute informar sem os zeros da esquerda (versão 4.00 do leiaute). |
CSC | string | entrada | informar o CSC - Código de Segurança do Contribuinte (antigo Token) , a SEFAZ alterou a nomenclatura de token para CSC [Manual de Especificações Técnicas do DANFE NFC-e e QRCode - v3.2]. |
versaoQRCode | string | entrada | informar a versão do QRCode, padrão = "100" ou "2" (versão 4.00 do leiaute) |
URLConsulta | string | entrada | A URL do portal de consulta da NFC-e é obtida pela DLL no arquivo ws3.xml com base no grupo da UF informada no XML da NFC-e, caso o usuário informe a URL, ela será utilizada para gerar a URL de consulta da NFC-e. Consulte as URL no ENCAT |
urlChave | string | entrada | Texto com a URL de consulta por chave de acesso a ser impressa no DANFE NFC-e. Informar a URL da “Consulta por chave de acesso da NFC-e”. A mesma URL que deve estar informada no DANFE NFC-e para consulta por chave de acesso Consulte as URL no ENCAT. (campo novo) |
indSinc | string | entrada | indicador de processamento síncrono (0=não ou 1=sim), este parâmetro será utilizado para criar o lote de envio. |
resultado | inteiro | saída | retorna o código do resultado da chamada da DLL |
msgResultado | string | saída | retorna a literal do resultado da chamada da DLL |
lote | string | saída | retorna uma estrutura de lote que contem a NFCe e pode ser enviada pela funcionalidade EnviaLoteV3 |
URLNFCe | string | saída | retorna a URL de consulta da NFC-e gerada. |
Retorno:
O resultado da chamada da assinatura é uma string com o XML assinado.
Integridade da Assinatura Digital
A assinatura digital é o resultado da aplicação de critografia assimétrica no resumo da mensagem (message digest) com a chave privada do assinante. Qualquer alteração do conteúdo do XML da NF-e tem reflexo no resumo da mensagem e invalida a assinatura digital. A DLL elimina todos os espaços em branco e outros caracteres de formatação como tab/CR/LF do XML da NF-e antes de aplicar a assinatura digital, assim o arquivo XML assinado não deve ser modificado em nenhuma hipótese para não invalidar a assinatura digital.
Outras causas que comprometem a validade da assinatura digital
O projeto da assinatua digital prevê que os arquivos XML utilizem a codificação UTF-8. A maioria das aplicações trabalham com a codificação ANSI que tem divergência na representação dos caracteres especiais (Ex. Ç, º, Á, etc). A forma mais simples de evitar os reflexos do uso de caracteres especiais é vedar a sua utilização como faz o aplicativo emissor de NF-e de SP, existem UF que não aceitam caracteres especiais como é o caso do MT. Em geral, o problema acontece quando o destinatário da NF-e tenta importar o arquivo XML da NF-e no aplicativo visualizador da RFB e o provedor de solução é acionado que aciona o nosso suporte... Conhecendo estas particularidades é possível conviver com os caracteres especiais, o problema todo está na fase que o XML é gerado em arquivo, como já dito as aplicações trabalham em uma codificação diferente do UTF-8 e gravamos o arquivo sem alterar a codificação e o arquivo XML tem a declaração XML no início do arquivo onde dizemos que estamos adotando a codificação UTF-8. A codificação ANSI e UTF-8 é igual até o caractere 127, os caracteres especias tem codificação diferente, por exemplo o caractere º tem representação diferente no ANSI (ba em hexadecimal) e no UTF-8 (c2 ba em hexadecimal), o grande problema é que o UTF-8 é multibyte e alguns caracteres são representados com 2, 3 ou 4 bytes e neste processo pode ocorrer o acréscimo de algum byte com reflexo na assinatura digital.
Caractere símbolo código ANSI (hexadecimal) código UTF-8 (hexadecimal) símbolo de numeral º ba c2 ba A com til à c3 c3 83 a com til ã e3 c3 a3 cecedilha minúsculo ç e7 c3 A7 cecedilha maiúsculo Ç c7 c3 87 Para evitar este tipo de problema, basta fazer a conversão da codificação de ANSI para UTF-8 na string antes da gravação do arquivo XML, para outros detalhes vide o post: Distribuição da NF-e para o Destinatário.
Obs: A aplicação da conversão da codificação só deve ser feita de ANSI para UTF-8, se a string já estiver em UTF-8 a aplicação da conversão vai corromper o conteúdo da string!
Assinatura de NF-e em uma estrutura de lote
A DLL não permite a assinatura de uma NF-e contida em uma estrutura de lote de NF-e, assim, a assinatura da NF-e deve ser realizada individualmente.
O uso de namespaces
A tag raiz do XML deve ter o namespace do projeto (xmlns="http://www.portalfiscal.inf.br/nfe") e nada mais, evite o uso de outros namespaces, pois apesar de aceitos em algumas UF, podem causar falhas na validação da assinatura digital.
Exemplo de uso de namespace recomendado: <NFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="2.00">
PRETENDO FAZER O ENVIO DE UMA NF-e POR VEZ
Muitas empresas emitem uma pequena quantidade notas fiscais durante o dia, não justificando a formação de lote de NF-e para envio à SEFAZ. A DLL oferece uma opção de envio individual de NF-e que não requer que a NF-e esteja assinada, pois a funcionalidade de envio valida o schema XML, assina a NF-e, monta o lote e faz a transmissão. Assim, não assine a NF-e caso pretenda utilizar a funcionalidade de envio individual de NF-e.
Armazenamento da NF-e
Recomendamos fortemente que grave o arquivo XML assinado, pois ele poderá ser útil no futuro em caso de algum problema. Não converta a string do XML assinado em UTF-8, pois este processo altera a codificação dos caracteres especiais para a codificação UTF-8 e muitos usuários importam arquivo convertido em UTF-8 para a aplicação sem converter a string lida para ANSI que é a codificação padrão de muitos ambientes de programação e acabam corrompendo o arquivo sem perceber.
O usuário deve arquivar o XML da NF-e assinado da forma que entender mais conveniente, como por exemplo:
. campo tipo blob do BD;
. arquivo no file system.Também é conveniente que exista alguma forma simples e automática de armazenamento de segurança, como por exemplo:
. envio do arquivo via e-mail para uma conta de e-mail do tipo gmail;
. uso de disco virtual do tipo dropbox.
O resultado da assinatura é o código numérico devolvido no parâmetro resultado com os seguintes significados:
código | Mensagem | origem | regra |
---|---|---|---|
5300 | Assinatura realizada com sucesso | DLL | - |
5301 | Erro: Certificado digital inexistente para [nome informado], verifique se o Assunto (subject name) está correto), ou talvez o certificado digital esteja fora do prazo de validade ou não esteja instalado para o usuário.. | DLL | - |
5302 | Erro: A tag de assinatura [nome da tag informada para a DLL] inexiste, verifique o nome da tag informada, Ex. de tag válida: infNFe | DLL | - |
5303 | Erro: A tag de assinatura [nome da tag informada para a DLL] não é unica, a assinatura deve ser realizada em uma NF-e, a NF-e deve ser inserida no lote somente após o processo de assinatura. | DLL | - |
5304 | Erro: Tentativa de assinar uma NF-e contida em um lote, a assinatura deve ser realizada em uma NF-e fora do lote, devendo ser inserida no lote somente após o processo de assinatura. | DLL | - |
5305 | Erro: Falha no acesso ao XML, XML mal formado ou XML vazio: [mensagem de erro] | DLL | - |
5306 | Erro: Falha no acesso do certificado digital: [mensagem de ERRO DO WINDOWS] | DLL | - |
5307 | Erro: Falha na Assinatura: [mensagem do ERRO DO WINDOWS] - vide guia de uso da DLL - https://www.flexdocs.net/guiaNFe/FAQ.assinatura.html | DLL | - |
5403 | Erro: Falha ao acessar certificado digital [mensagem de ERRO DO WINDOWS] | DLL | - |
5404 | Erro: Nenhum certificado digital selecionado | DLL | |
5405 | Erro: Nenhum certificado válido foi encontrado com o nome [NomeCertificado] informado no repositório [MY do CurrentUser] | DLL | - |
5406 | Erro: Falha no tratamento do parâmetro nome: [nome informado] | DLL | - |
5407 | Erro: Quantidade de parâmetos inválido: [nome informado] | DLL | - |
5408 | Erro: Falha na criação do objeto certificate: [mensagem do ERRO DO WINDOWS] | DLL | - |
8401 | Erro: O parâmetro idToken deve ser informado | DLL | - |
8402 | Erro: O parâmetro CSC deve ser informado | DLL | - |
8403 | Erro: O parâmetro versaoQRCode deve ser informada | DLL | - |
8404 | Erro: O parâmetro xml da NFCe deve ser informado | DLL | - |
8405 | Erro: O XML da NFC-e informado mal formado: Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8406 | Erro: Tag NFe não localizada no XML da NFC-e informado : XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8407 | Erro: Tag DigestValue não localizada no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8408 | Erro: Tag tpAmb não localizada no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8409 | Erro: O atributo Id da tag infNFe não localizada no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8410 | Erro: Tag dhEmi não localizada no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e[=conteúdo informado no parâmetro NFCe] | DLL | - |
8411 | Erro: Tag CNPJ/CPF/idEstrangeiro não localizado no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8412 | Erro: Tag vNF não localizada no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
8413 | Erro: Tag vICMS não localizada no XML da NFC-e informado : Erro=[Descrição do Erro], XML NFC-e=[conteúdo informado no parâmetro NFCe] | DLL | - |
5307 - Falha na Assinatura: [mensagem do ERRO DO WINDOWS]
O Erro 5307 é uma falha do certificado digital, ele pode não ter sido corretamente instalado ou não estar disponível para uso se for um token ou smart card.
A DLL acessa os certificados digitais existentes no provedor de certificados digitais (CSP) do Windows do usuário corrente (o que está logado no equipamento), desta forma para a DLL é indiferente se o certificado digital é do tipo A1 ou A3, desde que o certificado digital esteja corretamente instalado no CSP do Windows.
Assim, o problema de incompatibilidade do certificado digital ou do hardware criptográfico (smartcard/token) é com o framework .NET do Windows e não tem relação com a DLL, todas as aplicações que utilizam o framework .NET (Ex.: assinador da SEFAZ/RS) terão problema para usar o certificado digital se ele não for compatível com o Windows e não oferecer suporte necessário para o .NET Framework acessar a funcionalidade de cálculo de hash e criptográfia.
Compatibilidade do Certificado Digital com a versão do Windows
O usuário deve verificar se o smartcard/token adquirido é compatível com a versão do Windows e não tem incompatibilidade na assinatura XML com uso do framework .NET 2.0.
Teste do Certificado Digital
Os testes que são realizados pelo atendimento do fornecedor do certificado digital, em geral, limita-se a testar funcionalidade autenticação do usuário no e-CAC em algum outro Portal que exige autenticação mútua com envio do certificado digital e não faz o teste de assinatura digital XML que é a causa do Erro 5307.
Utilize aplicativos que utilizam o framework .NET 2.00, como por exemplo o assinador da SEFAZ/RS para ter uma segunda opinão. Uma aplicação que utiliza a biblioteca CAPICOM não serve de parâmetro para comparação.
Solução do problema
Desinstale o certificado digital e instale novamente conforme instruções do fornecedor do certificado digital.
Certificado Digital A1
A instalação de um certificado digital do tipo A1 requer o arquivo pfx (o arquivo com extensão cer não tem chave privada). Arquivos com extensão cer são arquivos de chave pública do certificado digital e não servem para uso em assinatura digital.
Certificado Digital A3
Se for um dispositivo A3 (token/smart card) verifique se os drivers e gerenciador criptográfico do seu dispositivo são compatíveis com a versão do Windows em uso.
drivers/gerenciadores para TOKEN
drivers/gerenciadores para SMARTCARD
O fornecedor do dispositivo também deve ser consultado para obter os drivers e gerenciadores corretos.
Certificado Digital CEF - CAIXA
Veja uma possível solução para certificado digital da CEF - CAIXA.
Histórico de atualização:
- 2017-08-15 - Versão preliminar.
- 13.1.3. Assinar NFC-e 4.00 [06-05-18]
13.1. Assinatura XML - « Anterior
13.1.2. Assinar NFC-e [07-10-15] - Próximo »
13.1.4. Validar Assinatura