11.1. Assinatura XML
11.1.1. Assinar
11.1. Assinatura XML
« Anterior
11.2. Certificado Digital
Próximo »

11.1.1. Assinar

Assinatura Digital XML no padrão do Projeto CT-e

Assinatura

int Assinar(string XMLString, string RefUri, string Nome, out string XMLAssinado, out string msgResultado)

Descrição:

Funcionalidade para realizar a assinatura digital no padrão XML Digital Signature enveloped em um documento XML.

A assinatura é realizada na tag informada no parâmetro RefUri do XML existente no conteúdo do parâmetro: XMLString.

É necessário informar o certificado digital que será utilizado para assinatura no parâmetro NomeCertificado.

Parâmetros:

nome tipo fluxo descrição
XMLString string entrada informar uma string com o XML que será assinado.
RefUri string entrada informar a tag que será assinada (Ex. infCte) com a referência da URI a ser assinada.
Nome string entrada informar o assunto do certificado que será utilizado para assinar o XML
XMLAssinado string saída retorna string XML assinada
msgResultado string saída resultado da chamada da DLL

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 criptografia assimétrica no resumo da mensagem (message digest) com a chave privada do assinante. Qualquer alteração do conteúdo do XML do CT-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 do CT-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 assinatua 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 do CT-e tenta importar o arquivo XML do CT-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 e º tem representação diferente no ANSI e no UTF-8, o grande problema é que o UTF-8 é multibyte e alguns caracteres são representados com 2 bytes e neste processo pode ocorrer o sumiço de algum byte com reflexo na assinatura digital. 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, com as devidas adequações ao projeto CT-e.

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 CT-e em uma estrutura de lote

A DLL não permite a assinatura de um CT-e contido em uma estrutura de lote de CT-e, assim, a assinatura do CT-e deve ser realizada individualmente.

O uso de namespaces

A tag raiz do XML deve ter o namespace do projeto (xmlns="http://www.cte.fazenda.gov.br/") 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.

O resultado da assinatura é o código numérico devolvido no parâmetro msgResultado com os seguintes significados:

código Mensagem
0 Assinatura realizada com sucesso
1 Erro: Problema ao acessar o certificado digital - exceção
2 Certificado digital inexistente para nome
3 XML mal formado + exceção
4 A tag de assinatura RefUri inexiste
5 A tag de assinatura RefUri não é unica
6 Erro Ao assinar o documento - ID deve ser string [RefUri(Atributo)]
7 Erro: Ao assinar o documento - exceção

Histórico de atualização:

Exemplos de uso:

Visual Basic 6.0

'
' declaração das variáveis que serão utilizadas na passagem de parâmetros da DLL
'
Dim XMLString As String     ' informar uma string com o XML que será assinado.
Dim RefUri As String        ' indica a tag a ser assinada (Ex. infCTe)
Dim Nome As String      ' informar o Nome do titular (campo Assunto) do certificado digital a ser utilizado na conexão SSL. Ex.: "CN=NFe - Associacao NF-e:99999090910270, C=BR, L=PORTO ALEGRE, O=Teste Projeto NFe RS, OU=Teste Projeto NFe RS, S=RS"
Dim XMLAssinado As String   ' retorna o XML assinado
Dim msgResultado As String  ' retorna a literal com resultado da chamada da DLL
Dim resultado As Long       ' retorna código do resultado da chamada da DLL
'
'
'  IMPORTANTE: todas as variáveis utilizadas como parâmetro da DLL devem ser inicializadas
'
'
Dim nomeArquivo As String   ' nome do arquivo que será assinado
'
nomeArquivo = "c:\exemplo.xml"
'
' importante: verificar a existência do arquivo solicitado na pasta do VB e indicar o caminho correto para ele
'   Carrega o conteúdo do nome do arquivo em XMLString
'
Open nomeArquivo For Input As #1
XMLString = Input$(LOF(1), 1)
Close #1
'
RefUri = "infCte"       ' indica a tag a ser assinada
msgResultado = ""
Nome = "CN=NFe - Associacao NF-e:99999090910270, C=BR, L=PORTO ALEGRE, O=Teste Projeto NFe RS, OU=Teste Projeto NFe RS, S=RS"
resultado = 0       '  retorna código do resultado da chamada da DLL
'
' referenciando a DLL em late binding
' não é necessário fazer o reference da DLL
' o intelisense não funciona
'
Dim objCTeUtil As Object
 
Set objCTeUtil = CreateObject("CTe_Util.Util")
 
Screen.MousePointer = vbHourglass    ' ponteiro ampulheta
'
'  houve alteração nos parâmetros de retorno, agora o XMLAssinado é devolvido pela funcionalidade
'
resultado = objCTeUtil.Assinar(XMLString, RefUri, Nome, XMLAssinado, msgResultado)
'
'
Screen.MousePointer = vbDefault      ' ponteiro normal
'
'  tratar retorno
'
If resultado = 0 Then
 
   '
   '  grava CT-e Assinado
   '
   nomeArquivo = "XMLAssinado.xml"
   Open nomeArquivo For Output As #1
   Print #1, XMLAssinado
   Close #1
 
MsgBox msgResultado + Chr(13) + Chr(13) + XMLAssinado, vbInformation, "Informação"
'
'
Else
 
MsgBox "Processo de assinatura falhou..." & vbCrLf & msgResultado, vbExclamation, "Atenção"
 
End If
'
'  liberar DLL
'
Set objCTeUtil = Nothing
11.1.1. Assinar
11.1. Assinatura XML
« Anterior
11.1. Assinatura XML
Próximo »
11.2. Certificado Digital