diff --git a/README.md b/README.md index 472e884a..9e8d33d2 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Projeto Para implementação do Java-Nfe Utilizando JAXB. ## Gostou do Projeto? Dê sua colaboração: [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TX9K693QQYA6W) Para Iniciar : -- Baixe o java-nfe-4.00.5.jar (https://github.com/Samuel-Oliveira/Java_NFe/raw/master/java-nfe-4.00.5b.jar) e o adicione às bibliotecas de Seu Projeto. +- Baixe o java-nfe-4.00.5.jar (https://github.com/Samuel-Oliveira/Java_NFe/raw/master/java-nfe-4.00.5.jar) e o adicione às bibliotecas de Seu Projeto. - Baixe o Schemas.rar (https://github.com/Samuel-Oliveira/Java_NFe/raw/master/Schemas.rar) e extraia na sua Máquina. - Maven : @@ -34,6 +34,8 @@ ________________________________________________________________________________ - Alterado Urls Consulta NFce GO - Adicionado Schemas Versão v1_51 - Adicionado Evento Epec +- Atualizado Cacert +- Atualizado Implementação para Ambiente Web - **Atenção: Atualizado Schemas faça o download Novamente.** ## v4.00.4 - 10-05-2018 diff --git a/java-nfe-4.00.5.jar b/java-nfe-4.00.5.jar new file mode 100644 index 00000000..56c159dc Binary files /dev/null and b/java-nfe-4.00.5.jar differ diff --git a/src/main/java/br/com/samuelweb/nfe/Assinar.java b/src/main/java/br/com/samuelweb/nfe/Assinar.java index 3b0b3ae7..81a2ef71 100644 --- a/src/main/java/br/com/samuelweb/nfe/Assinar.java +++ b/src/main/java/br/com/samuelweb/nfe/Assinar.java @@ -1,31 +1,17 @@ package br.com.samuelweb.nfe; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.UnrecoverableEntryException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import br.com.samuelweb.certificado.Certificado; +import br.com.samuelweb.certificado.CertificadoService; +import br.com.samuelweb.certificado.exception.CertificadoException; +import br.com.samuelweb.nfe.dom.ConfiguracoesNfe; +import br.com.samuelweb.nfe.exception.NfeException; +import br.com.samuelweb.nfe.util.XmlUtil; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import javax.xml.crypto.MarshalException; -import javax.xml.crypto.dsig.CanonicalizationMethod; -import javax.xml.crypto.dsig.DigestMethod; -import javax.xml.crypto.dsig.Reference; -import javax.xml.crypto.dsig.SignatureMethod; -import javax.xml.crypto.dsig.SignedInfo; -import javax.xml.crypto.dsig.Transform; -import javax.xml.crypto.dsig.XMLSignature; -import javax.xml.crypto.dsig.XMLSignatureException; -import javax.xml.crypto.dsig.XMLSignatureFactory; +import javax.xml.crypto.dsig.*; import javax.xml.crypto.dsig.dom.DOMSignContext; import javax.xml.crypto.dsig.keyinfo.KeyInfo; import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; @@ -39,17 +25,14 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import br.com.samuelweb.certificado.Certificado; -import br.com.samuelweb.certificado.CertificadoService; -import br.com.samuelweb.certificado.exception.CertificadoException; -import br.com.samuelweb.nfe.dom.ConfiguracoesNfe; -import br.com.samuelweb.nfe.exception.NfeException; -import br.com.samuelweb.nfe.util.XmlUtil; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.*; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * Classe Responsavel Por Assinar O Xml. @@ -58,160 +41,156 @@ */ class Assinar { - static final String INFINUT = "infInut"; - static final String EVENTO = "evento"; - - private static PrivateKey privateKey; - - private static KeyInfo keyInfo; - - Assinar assinarXMLsCertfificadoA1; - - /** - * @param stringXml - * @param tipo - * ('NFe' para nfe normal , 'infInut' para inutilizacao, 'evento' - * para eventos) - * @return String do Xml Assinado - * @throws NfeException - */ - static String assinaNfe(ConfiguracoesNfe config, String stringXml, String tipo) throws NfeException { - - stringXml = XmlUtil.removeAcentos(stringXml); - stringXml = assinaDocNFe(config, stringXml, tipo); - - return stringXml; - } - - /** - * Assinatura do XML de Envio de Lote da NF-e utilizando Certificado Digital. - * - * @param Conteudo - * do Xml - * @param Nome - * do Certificado Digital - * @return String do XMl Assinado - * @throws Exception - */ - private static String assinaDocNFe(ConfiguracoesNfe config, String xml, String tipo) throws NfeException { - - try { - Document document = documentFactory(xml); - XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM"); - ArrayList transformList = signatureFactory(signatureFactory); - loadCertificates(config, signatureFactory); - - for (int i = 0; i < document.getDocumentElement().getElementsByTagName(tipo).getLength(); i++) { - assinarNFe(tipo, signatureFactory, transformList, privateKey, keyInfo, document, i); - } - - return outputXML(document); - } catch (SAXException | IOException | ParserConfigurationException | NoSuchAlgorithmException - | InvalidAlgorithmParameterException | KeyStoreException | UnrecoverableEntryException - | NoSuchProviderException | CertificateException | CertificadoException | MarshalException - | XMLSignatureException e) { - throw new NfeException("Erro ao Assinar Nfe" + e.getMessage()); - } - } - - private static void assinarNFe(String tipo, XMLSignatureFactory fac, ArrayList transformList, - PrivateKey privateKey, KeyInfo ki, Document document, int indexNFe) throws NoSuchAlgorithmException, - InvalidAlgorithmParameterException, MarshalException, XMLSignatureException { - - NodeList elements; - switch (tipo) { - case EVENTO: - elements = document.getElementsByTagName("infEvento"); - break; - case INFINUT: - elements = document.getElementsByTagName("infInut"); - break; - default: - elements = document.getElementsByTagName("infNFe"); - } - - org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(indexNFe); - String id = el.getAttribute("Id"); - - el.setIdAttribute("Id", true); - - Reference ref = fac.newReference("#" + id, fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, - null); - - SignedInfo si = fac.newSignedInfo( - fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), - fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); - - XMLSignature signature = fac.newXMLSignature(si, ki); - - DOMSignContext dsc; - - if (tipo.equals(INFINUT)) { - dsc = new DOMSignContext(privateKey, document.getFirstChild()); - } else { - dsc = new DOMSignContext(privateKey, - document.getDocumentElement().getElementsByTagName(tipo).item(indexNFe)); - } - - dsc.setBaseURI("ok"); - - signature.sign(dsc); - } - - private static ArrayList signatureFactory(XMLSignatureFactory signatureFactory) - throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { - - ArrayList transformList = new ArrayList(); - TransformParameterSpec tps = null; - Transform envelopedTransform = signatureFactory.newTransform(Transform.ENVELOPED, tps); - Transform c14NTransform = signatureFactory.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", tps); - - transformList.add(envelopedTransform); - transformList.add(c14NTransform); - return transformList; - } - - private static Document documentFactory(String xml) throws SAXException, IOException, ParserConfigurationException { - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - return factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); - } - - private static void loadCertificates(ConfiguracoesNfe config, XMLSignatureFactory signatureFactory) - throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException, NoSuchProviderException, - CertificateException, IOException, CertificadoException { - - Certificado certificado = config.getCertificado(); - KeyStore keyStore = CertificadoService.getKeyStore(certificado); - - KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(certificado.getNome(), - new KeyStore.PasswordProtection(certificado.getSenha().toCharArray())); - privateKey = pkEntry.getPrivateKey(); - - KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory(); - List x509Content = new ArrayList(); - - x509Content.add(CertificadoService.getCertificate(certificado, keyStore)); - X509Data x509Data = keyInfoFactory.newX509Data(x509Content); - keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data)); - } - - private static String outputXML(Document doc) throws NfeException { - - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer trans = tf.newTransformer(); - trans.transform(new DOMSource(doc), new StreamResult(os)); - String xml = os.toString(); - xml = xml.replaceAll("\\r\\n", ""); - xml = xml.replaceAll(" standalone=\"no\"", ""); - return xml; - } catch (TransformerException e) { - throw new NfeException("Erro ao Transformar Documento:" + e.getMessage()); - } - - } + static final String INFINUT = "infInut"; + static final String EVENTO = "evento"; + + private static PrivateKey privateKey; + + private static KeyInfo keyInfo; + + Assinar assinarXMLsCertfificadoA1; + + /** + * @param stringXml + * @param tipo ('NFe' para nfe normal , 'infInut' para inutilizacao, 'evento' + * para eventos) + * @return String do Xml Assinado + * @throws NfeException + */ + static String assinaNfe(ConfiguracoesNfe config, String stringXml, String tipo) throws NfeException { + + stringXml = XmlUtil.removeAcentos(stringXml); + stringXml = assinaDocNFe(config, stringXml, tipo); + + return stringXml; + } + + /** + * Assinatura do XML de Envio de Lote da NF-e utilizando Certificado Digital. + * + * @param Conteudo do Xml + * @param Nome do Certificado Digital + * @return String do XMl Assinado + * @throws Exception + */ + private static String assinaDocNFe(ConfiguracoesNfe config, String xml, String tipo) throws NfeException { + + try { + Document document = documentFactory(xml); + XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM"); + ArrayList transformList = signatureFactory(signatureFactory); + loadCertificates(config, signatureFactory); + + for (int i = 0; i < document.getDocumentElement().getElementsByTagName(tipo).getLength(); i++) { + assinarNFe(tipo, signatureFactory, transformList, privateKey, keyInfo, document, i); + } + + return outputXML(document); + } catch (SAXException | IOException | ParserConfigurationException | NoSuchAlgorithmException + | InvalidAlgorithmParameterException | KeyStoreException | UnrecoverableEntryException + | CertificadoException | MarshalException + | XMLSignatureException e) { + throw new NfeException("Erro ao Assinar Nfe" + e.getMessage()); + } + } + + private static void assinarNFe(String tipo, XMLSignatureFactory fac, ArrayList transformList, + PrivateKey privateKey, KeyInfo ki, Document document, int indexNFe) throws NoSuchAlgorithmException, + InvalidAlgorithmParameterException, MarshalException, XMLSignatureException { + + NodeList elements; + switch (tipo) { + case EVENTO: + elements = document.getElementsByTagName("infEvento"); + break; + case INFINUT: + elements = document.getElementsByTagName("infInut"); + break; + default: + elements = document.getElementsByTagName("infNFe"); + } + + org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(indexNFe); + String id = el.getAttribute("Id"); + + el.setIdAttribute("Id", true); + + Reference ref = fac.newReference("#" + id, fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, + null); + + SignedInfo si = fac.newSignedInfo( + fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), + fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); + + XMLSignature signature = fac.newXMLSignature(si, ki); + + DOMSignContext dsc; + + if (tipo.equals(INFINUT)) { + dsc = new DOMSignContext(privateKey, document.getFirstChild()); + } else { + dsc = new DOMSignContext(privateKey, + document.getDocumentElement().getElementsByTagName(tipo).item(indexNFe)); + } + + dsc.setBaseURI("ok"); + + signature.sign(dsc); + } + + private static ArrayList signatureFactory(XMLSignatureFactory signatureFactory) + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { + + ArrayList transformList = new ArrayList(); + TransformParameterSpec tps = null; + Transform envelopedTransform = signatureFactory.newTransform(Transform.ENVELOPED, tps); + Transform c14NTransform = signatureFactory.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", tps); + + transformList.add(envelopedTransform); + transformList.add(c14NTransform); + return transformList; + } + + private static Document documentFactory(String xml) throws SAXException, IOException, ParserConfigurationException { + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + return factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); + } + + private static void loadCertificates(ConfiguracoesNfe config, XMLSignatureFactory signatureFactory) + throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException, CertificadoException { + + Certificado certificado = config.getCertificado(); + KeyStore keyStore = CertificadoService.getKeyStore(certificado); + + KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(certificado.getNome(), + new KeyStore.PasswordProtection(certificado.getSenha().toCharArray())); + privateKey = pkEntry.getPrivateKey(); + + KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory(); + List x509Content = new ArrayList(); + + x509Content.add(CertificadoService.getCertificate(certificado, keyStore)); + X509Data x509Data = keyInfoFactory.newX509Data(x509Content); + keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data)); + } + + private static String outputXML(Document doc) throws NfeException { + + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer trans = tf.newTransformer(); + trans.transform(new DOMSource(doc), new StreamResult(os)); + String xml = os.toString(); + xml = xml.replaceAll("\\r\\n", ""); + xml = xml.replaceAll(" standalone=\"no\"", ""); + return xml; + } catch (TransformerException e) { + throw new NfeException("Erro ao Transformar Documento:" + e.getMessage()); + } + + } } \ No newline at end of file diff --git a/src/main/java/br/com/samuelweb/nfe/Epec.java b/src/main/java/br/com/samuelweb/nfe/Epec.java index 6608703c..9239fbaf 100644 --- a/src/main/java/br/com/samuelweb/nfe/Epec.java +++ b/src/main/java/br/com/samuelweb/nfe/Epec.java @@ -1,5 +1,6 @@ package br.com.samuelweb.nfe; +import br.com.samuelweb.nfe.dom.ConfiguracoesNfe; import br.com.samuelweb.nfe.exception.NfeException; import br.com.samuelweb.nfe.util.ConstantesUtil; import br.com.samuelweb.nfe.util.XmlUtil; @@ -14,7 +15,7 @@ */ class Epec { - static TRetEnvEvento eventoEpec(TEnvEvento enviEvento, boolean valida, String tipo) throws NfeException { + static TRetEnvEvento eventoEpec(ConfiguracoesNfe config, TEnvEvento enviEvento, boolean valida, String tipo) throws NfeException { try { @@ -22,7 +23,7 @@ static TRetEnvEvento eventoEpec(TEnvEvento enviEvento, boolean valida, String ti xml = xml.replaceAll(" xmlns:ns2=\"http://www.w3.org/2000/09/xmldsig#\"", ""); xml = xml.replaceAll("