- 13. Funcionalidades
13.1. Assinar - 13. Funcionalidades
« Anterior - 13.2. Pega o nome do certificado digital
Próximo »
13.1. Assinar
Assinatura Digital XML no padrão do Projeto NF-e
Assinatura
string Assinar(string XMLString, string tag, string atributo, string NomeCertificado, out int resultado, 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 tag identificada pelo parâmetro atributo 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.
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 resssltar 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.
Parâmetros:
| nome | tipo | fluxo | descrição |
|---|---|---|---|
| XMLString | string | entrada | informar uma string com o XML que será assinado. |
| tag | string | entrada | informar a tag que será assinada Ex. infRps para RPS, LoteRps para Lote de RPS, etc., se omitida (""), a assinatura será realizada na tag raiz do XML. |
| atributo | string | entrada | informar o atributo da tag que será utilizado para identificar a assinatura, Ex. "id", "Id", etc., se a tag for omitida (""), este parâmetro é ignorado. |
| 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". (novas opções) |
| resultado | inteiro | saída | retorna o código do resultado da chamada do WS |
| msgResultado | string | saída | retorna a literal do resultado da chamada do WS |
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 do RPS 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 RPS 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 RPS ou NFS-e tenta abrir o arquivo pelo browser. 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.
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 um RPS em uma estrutura de lote
A DLL não permite a assinatura de um RPS contida em uma estrutura de lote de RPS, assim, a assinatura do RPS deve ser realizada individualmente.
O uso de namespaces
A tag raiz do XML deve ter o namespace adotado pela prefeitura, evite o uso de outros namespaces, pois apesar de aceitos, podem causar falhas na validação da assinatura digital.
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 no Repositório [MY do CurrentUser ou MY do LocalMachine] com Assunto [{0:0}], 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 [{0:0}] inexiste, verifique o nome da tag informada, Ex. de tag válida: infRps | DLL | - |
| 5303 | Erro: A tag de assinatura [{0:0}] não é unica, a assinatura deve ser realizada em um RPS, o RPS deve ser inserida no lote somente após o processo de assinatura. | DLL | - |
| 5304 | Erro: O atributo [{0:0}] inexistente na tag [{1:0}]. | DLL | - |
| 5305 | Erro: Falha no acesso ao XML (XML mal formado, XML vazio ou XML não informado): [{0:0}] | DLL | - |
| 5306 | Erro: Falha no acesso do certificado digital: [{0:0}] | DLL | - |
| 5307 | Erro: O parâmetro atributo deve ser informado. | DLL | - |
| 5308 | Erro: Falha na Assinatura: [{0:0}] - vide guia de uso da DLL - http://www.flexdocs.com.br/guiaNFSe/funcao.assinar.html | DLL | - |
Falha na Assinatura
O certificado digital é responsável pela falha na assinatura, as principais causas são:
Uso de Certificado Digital sem chave privada - é comum o desenvolvedoer receber o arquivo de certificado digital de seu cliente sem a chave privada, este tipo de arquivo tem extensão cer, se este for o caso solicite o arquivo novamente e peça para exportar a chave privada. o arquivo gerado deve ter a extensão pfx e será protegido por senha.
Certificado Digital do tipo A3 ausente - o certificado digital do tipo A3 pode estar com mal contato ou ausente, tente reconectar o dispositivo e verifique o status do certificado digital no aplicativo de administração do certificado digital.
Certificado Digital do tipo A1 da CEF
Existe um "macete" para utilizar o certificado digital da CAIXA:
O problema deste certificado é que apesar de ser um certificado digital A1, ele age como se fosse um certificado digital A3 e utiliza o CSP próprio (cefcert.dll que fica na pasta csp da aplicação da caixa), que não tem suporte para o tipo de assinatura do projeto (só funciona para autenticação).
Assim, é necessário fazer com que o certificado utilize o CSP do Windows.
Os passos são:
- instalar o certificado digital conforme orientação da CEF;
- verificar o funcionamento do certificado e que o certificado consta da lista de certificados no Internet Explorer;
- exportar o certificado digital pelo Internet Explorer;
- desinstalar o aplicativo da CAIXA;
- verificar se a DLL não ficou na pasta da aplicação da CAIXA;
- importar o certificado digital exportado no item 3.
Os passos acima funcionam para windows XP e vista, mas não existe garantia de funcionamento para o windows 7, assim se o equipamento tiver windows 7, tente fazer o processo em um equipamento que tenha windows XP, o certificado gerado no item 3 deve funcionar no windows 7.
Reinstale o Certificado Digital - se não for nenhum dos casos acima, tente reinstalar o certificado digital novamente.
Histórico de atualização:
- 2011-01-07 - v1.0i - Versão preliminar.
- 2010-10-23 - v1.0e - Versão preliminar.
- 13.1. Assinar
13. Funcionalidades - « Anterior
13. Funcionalidades - Próximo »
13.2. Pega o nome do certificado digital
Download do Manual da CAIXA