Depois de nos matarmos para entender o funcionamento, noites em claro para testes e mais testes, a SEFAZ – Salvador disponibilizou uma DLL e um conjunto de c??digos-fonte para realizar todo o processo de assinatura e envio. Agora ?? m??o na roda para quem ir?? come??ar a implementar. Para quem j?? passou por esse sofrimento agora ?? s?? descan??o… Para mais informa????es acesse aqui. Abaixo tem os links dos principais arquivos para o utilit??rio, documentos e XMLs de exemplo:
Categoria: nota fiscal eletr??nica
Desde que lan??aram a nota fiscal eletr??nica, n??s programadores ficamos com receio do uso das leitoras e cart??es nos sistemas operacionais para a assinatura do XML usando o certificado digital. Geralmente os servidores usufruem de alguma vers??o do Windows Server para acomodar as aplica????es web (que realizam o processo de assinatura) al??m de proporcionar mais robustez e qualidade diante dos trabalhos. Mas as leitoras e cart??es simplesmente n??o funcionam como deveriam! Incompatibilidade… dizem.
Enfim… como fazer? Simplesmente ?? s?? usar outro sistema operacional!
“Mas como vou usar se meu servidor ?? Windows Server e n??o posso instalar outro SO?” (Voc?? se perguntando)
Resposta: Use os dois atrav??s de uma m??quina virtual! H?? v??rios tipos e para v??rios gostos ficando a crit??rio do que voc?? for utilizar. Recomendo o VMware! Ele disp??e de duas vers??es (h?? outras que voc?? pode optar tamb??m) que s??o ??timas para uso: Player e Server. Em resumo, a Player ?? limitada pois seu uso ?? simples mas n??o deixa de ser ??til.
Vamos ao processo que ser?? bem simples:
- Instale uma das vers??es do VMware;
- Instale um Windows 2000/XP/Vista nela contanto que seja compat??vel com sua leitora/cart??o (a instala????o ?? bem simples e sem dificuldades – ?? mais f??cil do que quando vai instalar no computador “de verdade” bastando seguir o Wizard dela);
- Agora conecte a leitora do cart??o no PC. Note que no Windows Server n??o acontecer?? nada, mas no Windows interno come??ar?? a instala????o;
- Em seguida espete o cart??o na leitora;
- Abra o utilit??rio da leitora (atrav??s do Windows da m??quina virtual) e ver?? que o cart??o foi lido corretamente.
Pronto! Da?? basta compartilhar uma pasta entre o Windows Server e a m??quina virtual (atrav??s do VMWare se faz isso) e, enquanto no Windows Server vai jogando os XMLs nessa pasta, o Windows MV (da m??quina virtual) vai assinando/enviando. Bem louco, n??o? Mas funciona! Pode at?? ter o Linux virtualizando um Windows que a leitora ir?? funcionar.
Lendo aquele bolo de especifica????o da ABRASF muitos devem perguntar: “Certo, sei quais campos colocar no XML mas qual a ordem do processo de assinatura?”. A documenta????o n??o fica claro realmente como e qual a melhor forma de assinar. Realize a seguinte ordem:
- Gere o XML da Rps e assine;
- Se for enviar mais de uma Rps em um mesmo lote, repita o passo 1 para cada Rps;
- Anexe todas as Rps j?? assinadas no XML do Lote;
- Assine o Lote e fa??a o envio.
Seu XML de envio deve ficar semelhante ?? figura abaixo:
Para fazer a assinatura dos XMLs, utilize a fun????o abaixo:
private XmlDocument AplicaAssinatura(string xml, string uri)
{
try
{
// Obtem o certificado
X509Certificate2 X509Cert = ObtemCertificado();
// Cria um documento XML para carregar o XML
XmlDocument docXML = new XmlDocument();
docXML.PreserveWhitespace = true;
// Carrega o documento XML
docXML.LoadXml(xml);
// Cria o objeto XML assinado
SignedXml signedXml = new SignedXml(docXML);
// Assina com a chave privada
signedXml.SigningKey = X509Cert.PrivateKey;
// Atribui o m??todo de canoniza????o
signedXml.SignedInfo.CanonicalizationMethod = “http://www.w3.org/TR/2001/REC-xml-c14n-20010315”;
// Atribui o m??todo para assinatura
signedXml.SignedInfo.SignatureMethod = “http://www.w3.org/2000/09/xmldsig#rsa-sha1”;
// Cria a referencia
Reference reference = new Reference();
// Pega a URI para ser assinada
XmlAttributeCollection _Uri = docXML.GetElementsByTagName(uri).Item(0).Attributes;
foreach (XmlAttribute _atributo in _Uri)
{
if (_atributo.Name == “id”)
reference.Uri = “#” + _atributo.InnerText;
}
// Adiciona o envelope ?? refer??ncia
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Atribui o m??todo do Hash
reference.DigestMethod = “http://www.w3.org/2000/09/xmldsig#sha1”;
// Adiciona a referencia ao XML assinado
signedXml.AddReference(reference);
// Cria o objeto keyInfo
KeyInfo keyInfo = new KeyInfo();
// Carrega a informa????o da KeyInfo
KeyInfoClause rsaKeyVal = new RSAKeyValue((System.Security.Cryptography.RSA)X509Cert.PrivateKey);
KeyInfoX509Data x509Data = new KeyInfoX509Data(X509Cert);
x509Data.AddSubjectName(X509Cert.SubjectName.Name.ToString());
keyInfo.AddClause(x509Data);
keyInfo.AddClause(rsaKeyVal);
// Adiciona a KeyInfo
signedXml.KeyInfo = keyInfo;
// Atribui uma ID ?? assinatura
signedXml.Signature.Id = “Assigned” + uri;
// Efetiva a assinatura
signedXml.ComputeSignature();
// Obtem o XML assinado
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Adiciona o elemento assinado ao XML
docXML.DocumentElement.AppendChild(docXML.ImportNode(xmlDigitalSignature, true));
// Retorna o XML
return docXML;
}
catch (Exception erro) { throw erro; }
}
O par??metro URI ?? o nome da tag geral que deve ser assinada de um XML, no caso dever?? assinar as tags InfRps (cada uma) e LoteRps. A fun????o ObtemCertificado j?? foi exibida aqui em um t??pico anterior que serve para captura do certificado digital.
Post r??pido sobre Nota Fiscal Eletr??nica… Caso esteja desenvolvendo a aplica????o de NFe para um PF e/ou PJ e esteja utilizando certificados do tipo A3 (no A1 deve servir tamb??m, mas ainda n??o testei), utilize a fun????o abaixo para capturar da leitora o certificado. Os dados s??o armazenados no objeto para posterior manipula????o, exemplo, assinatura do XML para envio.
using System.Security.Cryptography.X509Certificates;
X509Certificate2 oX509Cert = new X509Certificate2();
X509Store store = new X509Store(“MY”, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection collection1 = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection collection2 = (X509Certificate2Collection)collection.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, false);
X509Certificate2Collection scollection = (X509Certificate2Collection)collection2.Find(X509FindType.FindBySubjectName, “NOME DA EMPRESA PESSOA”, false);
if (scollection.Count == 0)
oX509Cert = null;
else
oX509Cert = scollection[0];
No objeto oX509Cert ?? o objeto representativo de seu certificado digital no seu sistema. Geralmente esse tipo de certificado fica armazenado temporariamente na pasta Pessoal do Gerenciador de Certificados do Windows. Caso deseje visualizar qual o nome correto do certificado e realizar demais opera????es, v?? em Iniciar, Executar e digite certmgr.msc. Uma tela como essa ir?? surgir:
Se o seu certificado n??o aparecer a??, deve ser que o leitor n??o est?? reconhecendo o cart??o, ou o software de leitura n??o foi corretamente instalado e outros fatores que agora n??o entrar?? em detalhes.
Como a partir de 01 de Abril a Nota Fiscal n??o ser?? mais aquela de papel, come??aram a algum tempo a emiss??o da eletr??nica e consequentemente, n??s programadores, ficamos respons??veis de realizar a integra????o dos diversos sistemas ?? esse novo tipo de implanta????o. N??o diferente de voc?? tamb??m fui obrigado a adentrar nesse mundo. Nunca li tanto de XML e sobre Certificado Digital na minha vida!
Por ventura j?? existiam alguns colegas que j?? realizaram grande parte do trabalho disponibilizando c??digos e bibliotecas nas mais variadas linguagens que nos ajudaram a realizar esse feitio. Um deles que testei ?? o UniNFe. Muito boa a implementa????o, al??m de ser OpenSource com c??digo em ASP.NET. Bem f??cil de configurar e j?? faz tudo: assina seu XML, realiza o envio e obt??m o retorno. Fica apenas o trabalho do usu??rio gerar o XML de envio e ler o de retorno.
Quando utilizei, pensei: “Pronto! Problemas resolvidos…”. O que era bom, ficou para tr??s. O UniNFe serve para emiss??o de notas fiscais cujo o contribuinte possua Inscri????o Estadual. Para empresas que n??o possuem IE, apenas a Inscri????o Municipal (IM), devem atrelar-se ?? implementa????o da SEFAZ do munic??pio cuja implementa????o difere, na maioria dos aspectos, dessa implementa????o. Contudo, por ser OpenSource, pude aproveitar algumas classes dele para gerar as minhas. Constantemente estou em contato com a secretaria de NFS-e em Salvador para resolu????o de meus problemas (e problemas) e tentar terminar tal solu????o.
Nos pr??ximos posts, logo que eu for resolvendo/terminando algumas funcionalidades, irei disponilizando trechos de classes/m??todos para gera????o da NF-e. Abaixo segue uma rela????o de links que podem ajud??-los a adiantarem algum c??digo:
- Nota Fiscal Eletr??nica Nacional: http://nf-eletronica.com/blog/
- Linha de C??digo – Nota Fiscal Eletr??nica – Gera????o, Assinatura e Transmiss??o: http://www.linhadecodigo.com.br/Artigo.aspx?id=1814
Mais materias e links s??o facilmente encontrados na net, dependendo do que for realmente fazer. N??o se esque??a de, antes de come??ar a implementar, leia o Manual da Integra????o para onde dever?? prestar conta: Munc??pio ou Estado.