wmixvideo / nfe

Nota Fiscal Eletrônica em Java.
Apache License 2.0
654 stars 377 forks source link

Permitir a utilização de certificados A3 #27

Closed jefperito closed 8 years ago

jefperito commented 9 years ago

Atualmente só existe a possibilidade de utilizar certificados A1

leonhardt commented 8 years ago

Seria interessante permitir o NFeConfig receber o tipo de certificado de forma dinâmica. Imagine que você tenha uma aplicação multitenancy(uma aplicação para muitos usuários) e tenha a necessidade de ao fazer a comunicação o tipo de certificado mudar de acordo com o usuário logado. Da forma que está vou precisar ter várias implementações do NFeConfig para cada tipo de certificado.

leonhardt commented 8 years ago

Deem uma olhada na implementação abaixo, seria bacana ter algo similar no momento de carregar o certificado, esse código abaixo utilizamos em produção e funciona para os certificados A3 e A1.

                     if (tipoCertificado.equals(DmTipoCertificado.A1)) {
                keyStoreA3 = KeyStore.getInstance("PKCS12");
                try (InputStream certificadoStream = new FileInputStream(config.getCertificado())) {
                    keyStoreA3.load(certificadoStream, config.getCertificadoSenha().toCharArray());
                }
            } else {
                String pkcs11config = null;

                if (tipoCertificado.equals(DmTipoCertificado.ETOKEN)) {
                    if (SystemUtils.IS_OS_MAC) {
                        pkcs11config = "name=eToken\nlibrary=/usr/local/lib/libeTPkcs11.dylib\n\rshowInfo=true";
                    } else {
                        pkcs11config = "name=eToken\nlibrary=c:\\Windows\\System32\\eTpkcs11.dll\n\rshowInfo=true";
                    }
                } else if (tipoCertificado.equals(DmTipoCertificado.SMARTCARD)) {
                    if (SystemUtils.IS_OS_MAC) {
                        pkcs11config = "name=eToken\nlibrary=/usr/local/lib/libaetpkss1.dylib\n\rshowInfo=true";
                    } else {
                        pkcs11config = "name=eToken\nlibrary=c:\\Windows\\System32\\aetpkss1.dll\n\rshowInfo=true";
                    }
                } else {
                    if (SystemUtils.IS_OS_MAC) {
                        pkcs11config = "name=eToken\nlibrary=/usr/local/lib/libcmp11.dylib\n\rshowInfo=true";
                    } else {
                        pkcs11config = "name=eToken\nlibrary=c:\\Windows\\System32\\cmp11.dll\n\rshowInfo=true";
                    }
                }

                byte[] pkcs11configBytes = pkcs11config.getBytes();
                ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11configBytes);
                SunPKCS11 p = new SunPKCS11(configStream);
                Security.addProvider(p);

                keyStoreA3 = KeyStore.getInstance("pkcs11", p);
                keyStoreA3.load(null, config.getCertificadoSenha().toCharArray());
            }
return keyStoreA3;
fincatto commented 8 years ago

Esse código é um pouco mais revelador. Basicamente o que difere um certificado do outro é o carregamento do KeyStore, é isso? Se for isso realmente, podemos arquitetar o sistema para que o carregamento do keystore em si seja feito dinamicamente. Inclusive com a possibilidade de o usuário criar uma nova classe extendendo uma interface e fazer esse carregamento de uma forma ainda não pensada. Está correto?

PS: há uma discussão em curso para separar as responsabilidades em passos (geracao, assinatura, envio): https://github.com/wmixvideo/nfe/issues/136 Estamos discutindo a implementação dessa arquitetura em uma futura versão 2.0, o que vocês acham (deixem seus comentários lá).

[]s

On Thu, May 5, 2016 at 10:33 AM, Felipe Leonhardt notifications@github.com wrote:

Deem uma olhada na implementação abaixo, seria bacana ter algo similar no momento de carregar o certificado, esse código abaixo utilizamos em produção e funciona para os certificados A3 e A1.

if (tipoCertificado.equals(DmTipoCertificado.A1)) { keyStoreA3 = KeyStore.getInstance("PKCS12"); try (InputStream certificadoStream = new FileInputStream(config.getCertificado())) { keyStoreA3.load(certificadoStream, config.getCertificadoSenha().toCharArray()); } } else { String pkcs11config = null;

            if (tipoCertificado.equals(DmTipoCertificado.ETOKEN)) {
                if (SystemUtils.IS_OS_MAC) {
                    pkcs11config = "name=eToken\nlibrary=/usr/local/lib/libeTPkcs11.dylib\n\rshowInfo=true";
                } else {
                    pkcs11config = "name=eToken\nlibrary=c:\\Windows\\System32\\eTpkcs11.dll\n\rshowInfo=true";
                }
            } else if (tipoCertificado.equals(DmTipoCertificado.SMARTCARD)) {
                if (SystemUtils.IS_OS_MAC) {
                    pkcs11config = "name=eToken\nlibrary=/usr/local/lib/libaetpkss1.dylib\n\rshowInfo=true";
                } else {
                    pkcs11config = "name=eToken\nlibrary=c:\\Windows\\System32\\aetpkss1.dll\n\rshowInfo=true";
                }
            } else {
                if (SystemUtils.IS_OS_MAC) {
                    pkcs11config = "name=eToken\nlibrary=/usr/local/lib/libcmp11.dylib\n\rshowInfo=true";
                } else {
                    pkcs11config = "name=eToken\nlibrary=c:\\Windows\\System32\\cmp11.dll\n\rshowInfo=true";
                }
            }

            byte[] pkcs11configBytes = pkcs11config.getBytes();
            ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11configBytes);
            SunPKCS11 p = new SunPKCS11(configStream);
            Security.addProvider(p);

            keyStoreA3 = KeyStore.getInstance("pkcs11", p);
            keyStoreA3.load(null, config.getCertificadoSenha().toCharArray());
        }

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217155559

leonhardt commented 8 years ago

Justamente Diego. Para o A1: KeyStore.getInstance("PKCS12"); Para o A3: KeyStore.getInstance("pkcs11", p);

Usamos dessa forma em produção, emitindo nota normalmente por A3

waldandrade commented 8 years ago

Com relação ao código "dinâmico" apresentado pelo Felipe, duas coisas a serem discutidas ...

Será que compensa internalizar assim a escolha do certificado? Sou a favor da configuração externa. Um arquivo que contém diversas propriedades, e pode ser alterado de dentro do sistema (no caso seria o sistema de cada um).

A esta biblioteca restaria apenas a função de dizer onde o arquivo deve estar salvo, e qual o formato do arquivo .... se é XML, JSON, etc.

Digo isso por que ... existem várias formas de implementar essa ferramenta, por applet, no meu caso em uma aplicação java normal, ou em um servidor. E se amanhã surgir outra tecnologia, com outra dll ..... o usuário da biblioteca teria que solicitar uma alteração?

2016-05-05 11:40 GMT-03:00 Felipe Leonhardt notifications@github.com:

Justamente Diego. Para o A1: KeyStore.getInstance("PKCS12"); Para o A3: KeyStore.getInstance("pkcs11", p);

Usamos dessa forma em produção, emitindo nota normalmente por A3

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217171952

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

waldandrade commented 8 years ago

Esse código poderia ser usado como default .. ou seja, se a propriedade não for definida ele seguir esse caminho, mas se for utilizar a propriedade definida. O que acha?

Em 5 de maio de 2016 12:12, Waldney Andrade waldney.andrade@gmail.com escreveu:

Com relação ao código "dinâmico" apresentado pelo Felipe, duas coisas a serem discutidas ...

Será que compensa internalizar assim a escolha do certificado? Sou a favor da configuração externa. Um arquivo que contém diversas propriedades, e pode ser alterado de dentro do sistema (no caso seria o sistema de cada um).

A esta biblioteca restaria apenas a função de dizer onde o arquivo deve estar salvo, e qual o formato do arquivo .... se é XML, JSON, etc.

Digo isso por que ... existem várias formas de implementar essa ferramenta, por applet, no meu caso em uma aplicação java normal, ou em um servidor. E se amanhã surgir outra tecnologia, com outra dll ..... o usuário da biblioteca teria que solicitar uma alteração?

2016-05-05 11:40 GMT-03:00 Felipe Leonhardt notifications@github.com:

Justamente Diego. Para o A1: KeyStore.getInstance("PKCS12"); Para o A3: KeyStore.getInstance("pkcs11", p);

Usamos dessa forma em produção, emitindo nota normalmente por A3

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217171952

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 <%2B55%2884%298894-3405> +55(84)9447-7354 <%2B55%2884%299447-7354>

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

waldandrade commented 8 years ago

@caiocteodoro não entendi ... todos obtiveram sucesso, ou apenas os que não precisam de assinatura?

caiocteodoro commented 8 years ago

@waldandrade

todos os servições estão funcionando corretamente com o certificado A3

caiocteodoro commented 8 years ago

como vamos implementar isso no projeto? Pelo que vi o @leonhardt postou um código diferente do meu, vamos deixar a cargo do usuário da lib ou vai ser algo mais automático?

leonhardt commented 8 years ago

@waldandrade Entendo a preocupação, algo válido com certeza. Mas olhando por outra ótica, atualmente tenho todos os quadros desenvolvidos em produção: 1 - Web + A1 e Applet(A3) 2 - Desktop + A1 e A3 Todos utilizam a mesma solução e com esse código de carregamento internalizado, mesmo porque eu preciso da KeyStore e a biblioteca já me devolve de acordo com o tipo do certificado tornando o processo muito mais simples, vale lembrar que aqueles caminhos das DLL's não mudam a anos são fixos e se mudarem é fácil também externalizar somente essa parte, não há necessidade de ser idêntico podemos melhorar.

A tempo e OFF-TOPIC que para quem possa estar pensando em implementar em Applet a Oracle no fim desse ano não dará mais suporte ao Applet para os navegadores, ou seja quem tem solução implementada não conseguirá rodar em versões mais novas do Java nos navegadores.

waldandrade commented 8 years ago

Creio que sua sugestão é super válida também. Creio que escolha dessa arquitetura é algo mais conceitual, mas dá para chegar em um meio termo. Por exemplo, deixar um processo default, mas permitir também a configuração.

Onde você carrega o "tipoCertificado"? Vi que você faz um teste nele.

Com relação a arquitetura de Applet, desenvolvi uma nova arquitetura que se baseia em no ACBRNFeMonitor, mas é integrado com o Google Drive.

https://github.com/waldandrade/NFeMonitor/tree/master

Em 5 de maio de 2016 12:57, Felipe Leonhardt notifications@github.com escreveu:

@waldandrade https://github.com/waldandrade Entendo a preocupação, algo válido com certeza. Mas olhando por outra ótica, atualmente tenho todos os quadros desenvolvidos em produção: 1 - Web + A1 e Applet(A3) 2 - Desktop + A1 e A3 Todos utilizam a mesma solução e com esse código de carregamento internalizado, mesmo porque eu preciso da KeyStore e a biblioteca já me devolve de acordo com o tipo do certificado tornando o processo muito mais simples, vale lembrar que aqueles caminhos das DLL's não mudam a anos são fixos e se mudarem é fácil também externalizar somente essa parte, não há necessidade de ser idêntico podemos melhorar.

A tempo e OFF-TOPIC que para quem possa estar pensando em implementar em Applet a Oracle no fim desse ano não dará mais suporte ao Applet para os navegadores, ou seja quem tem solução implementada não conseguirá rodar em versões mais novas do Java nos navegadores.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217193905

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

waldandrade commented 8 years ago

@caiocteodoro

Estou obtendo este arro ao consultar um lote ...

Caused by: java.security.InvalidKeyException: Unsupported key type: SunPKCS11-SmartCard RSA private key, 2048 bits (id 1, token object, sensitive, unextractable) at sun.security.mscapi.RSACipher.engineGetKeySize(RSACipher.java:425) at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1067) at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1025) at javax.crypto.Cipher.init(Cipher.java:1245) at java.security.Signature$CipherAdapter.engineInitSign(Signature.java:1282) at java.security.Signature$Delegate.init(Signature.java:1155) at java.security.Signature$Delegate.chooseProvider(Signature.java:1112) at java.security.Signature$Delegate.engineInitSign(Signature.java:1185) at java.security.Signature.initSign(Signature.java:550) at sun.security.ssl.RSASignature.engineInitSign(RSASignature.java:126) at java.security.Signature$Delegate.engineInitSign(Signature.java:1183) at java.security.Signature.initSign(Signature.java:550) at sun.security.ssl.HandshakeMessage$CertificateVerify.(HandshakeMessage.java:1585) at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1116) ... 35 more

NFLoteConsultaRetorno loteRecupetado = new WSFacade(nFeConfig).consultaLote(recibo, NFModelo.NFE);

leonhardt commented 8 years ago

@waldandrade Informo o tipoCertificado no NFeConfig similar ao que você fez, porém não deixo fixo. E criei uma classe util que carrega essa keyStore de acordo com o tipo, dessa forma as classes de Assinatura e de Envio utilizam essa classe útil para carregar o certificado, ao invés de estar fixo como é atualmente.

NFeConfigImpl.java
public class NFeConfigImpl implements NFeConfig
.....
public void setTipoCertificado(Integer tipoCertificado) {
        this.tipoCertificado = DmTipoCertificado.valueOfCodigo(tipoCertificado);
    }
.....
waldandrade commented 8 years ago

@caiocteodoro

Obtive o erro: Error signing certificate verify.

Li que aparentemente não podemos inserir o provider várias vezes no KeyStore. Como estou tentando a consulta logo após o envio, não está funcionando.

Farei alguns testes para me certificar.

caiocteodoro commented 8 years ago

vi isso também, estou fazendo um teste agora para ver se da certo..se conseguir tbm compartilha ai.

Em 5 de maio de 2016 13:42, waldandrade notifications@github.com escreveu:

@caiocteodoro https://github.com/caiocteodoro

Obtive o erro: Error signing certificate verify.

Li que aparentemente não podemos inserir o provider várias vezes no KeyStore. Como estou tentando a consulta logo após o envio, não está funcionando.

Farei alguns testes para me certificar.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217206239

waldandrade commented 8 years ago

Acabei de confirmar ... se eu rodo a consulta separado funciona, se eu rodo depois de enviar dá o erro.

leonhardt commented 8 years ago

Seguinte pessoal o código KeyStore.getInstance("pkcs11", p) só deve ser executado uma única vez para cada certificado A3, por isso o erro está ocorrendo. 1 - Carregar a instancia somente uma vez e guardar 2 - Executar o load keyStoreA3.load(certificadoStream, config.getCertificadoSenha().toCharArray()); toda a vez que for necessário utilizar

waldandrade commented 8 years ago

Creio que o problema está aqui:

com.fincatto.nfe310.webservices.NFSocketFactory

NFGeraCaminhoDllCertificadoA3 dll = new NFGeraCaminhoDllCertificadoA3(config);

            Provider provider = new sun.security.pkcs11.SunPKCS11(dll.getCaminhoArquivo());
            Security.addProvider(provider);
            ks = KeyStore.getInstance("pkcs11", provider); 
            ks.load(null, config.getCertificadoSenha().toCharArray());

Basicamente é isso @leonhardt @caiocteodoro

Como vocês sugerem que deve ficar?

leonhardt commented 8 years ago

Faz um teste carregando somente uma única vez a ks = KeyStore.getInstance("pkcs11", provider); deixando singleton.

if (ks == null){
Provider provider = new sun.security.pkcs11.SunPKCS11(dll.getCaminhoArquivo());
            Security.addProvider(provider);
            ks = KeyStore.getInstance("pkcs11", provider); 
}    
 ks.load.....

Perdoem a pressa

caiocteodoro commented 8 years ago

A NFSocketFactory deve ser carregada somente uma unica vez?

2016-05-05 14:01 GMT-03:00 waldandrade notifications@github.com:

Creio que o problema está aqui:

com.fincatto.nfe310.webservices.NFSocketFactory

NFGeraCaminhoDllCertificadoA3 dll = new NFGeraCaminhoDllCertificadoA3(config);

        Provider provider = new sun.security.pkcs11.SunPKCS11(dll.getCaminhoArquivo());
        Security.addProvider(provider);
        ks = KeyStore.getInstance("pkcs11", provider);
        ks.load(null, config.getCertificadoSenha().toCharArray());

Basicamente é isso @leonhardt https://github.com/leonhardt @caiocteodoro https://github.com/caiocteodoro

Como vocês sugerem que deve ficar?

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217210995

waldandrade commented 8 years ago

Consegui ....

ks = KeyStore.getInstance("pkcs11");
if(ks.getProvider() == null){
    ks = KeyStore.getInstance("pkcs11", provider);
}

Ela sempre deve ser carregada ... no entanto, se a KeyStore já estiver com um provider ela deve ser somente carregada, se não estiver ainda com um provider, tem que ser incluído o provider.

Alguém atualiza ai

caiocteodoro commented 8 years ago

boa meu caro @waldandrade

waldandrade commented 8 years ago

@caiocteodoro com isso, todas as funcionalidades ficam atendidas?

leonhardt commented 8 years ago

@waldandrade Bacana brow, no meu caso eu pego somente uma vez a instância, bastando fazer somente o load quando for utilizar. Que bom que assim deu certo também.

caiocteodoro commented 8 years ago

sim, todas estão funcionando corretamente. E a gora conseguimos fazer as chamadas em seguida

caiocteodoro commented 8 years ago

ta ficando top estas modificações.. Estão todos de parabéns!!! @waldandrade @leonhardt @fauker @fincatto

waldandrade commented 8 years ago

Fico feliz em contribuir friends.

waldandrade commented 8 years ago

Você testou o A1? importante para ver se tá tudo funcionando. Se alguém tiver como testar Linux, e Mac.

caiocteodoro commented 8 years ago

no certificado A3 (linux, mac) muda o caminho da dll Dai precisa adicionar na classe que cria o arquivo de configuração Não tenho acesso a nenhuma dessas plataformas se alguém puder fazer!

Agora para o A1 vou testar aqui e já dou o retorno.

waldandrade commented 8 years ago

@leonhardt Acho interessante abrir um tópico só para discutirmos essas dinamicidades e automaticidades da biblioteca.

Deixar tudo automático? Criar uma forma de configuração mais dinâmica? Achar um meio termo?

leonhardt commented 8 years ago

@waldandrade Concordo, perfeito.

caiocteodoro commented 8 years ago

Boa ideia, achar um meio termo seria perfeito.

E a propósito acabei de testar a LIB utilizando o certificado A1, e está tudo OK. As modificações para comportar o certificado A3 não atrapalhou em nada.

waldandrade commented 8 years ago

Ótimo ... ai fica a cargo do amigo @fincatto avaliar e fazer o merge.

Em 5 de maio de 2016 15:00, caiocteodoro notifications@github.com escreveu:

Boa ideia, achar um meio termo seria perfeito.

E a propósito acabei de testar de testar a LIB utilizando o certificado A1, e está tudo OK. As modificações para comportar o certificado A3 não atrapalhou em nada.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217227295

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

waldandrade commented 8 years ago

parabéns @caiocteodoro e Leonardo

Em 5 de maio de 2016 15:39, Waldney Andrade waldney.andrade@gmail.com escreveu:

Ótimo ... ai fica a cargo do amigo @fincatto avaliar e fazer o merge.

Em 5 de maio de 2016 15:00, caiocteodoro notifications@github.com escreveu:

Boa ideia, achar um meio termo seria perfeito.

E a propósito acabei de testar de testar a LIB utilizando o certificado A1, e está tudo OK. As modificações para comportar o certificado A3 não atrapalhou em nada.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217227295

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 <%2B55%2884%298894-3405> +55(84)9447-7354 <%2B55%2884%299447-7354>

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

fincatto commented 8 years ago

Essa semana tá bem corrida pra mim, mas quero fazer o merge no final de semana já! []s

2016-05-05 15:39 GMT-03:00 waldandrade notifications@github.com:

parabéns @caiocteodoro e Leonardo

Em 5 de maio de 2016 15:39, Waldney Andrade waldney.andrade@gmail.com escreveu:

Ótimo ... ai fica a cargo do amigo @fincatto avaliar e fazer o merge.

Em 5 de maio de 2016 15:00, caiocteodoro notifications@github.com escreveu:

Boa ideia, achar um meio termo seria perfeito.

E a propósito acabei de testar de testar a LIB utilizando o certificado A1, e está tudo OK. As modificações para comportar o certificado A3 não atrapalhou em nada.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217227295

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 <%2B55%2884%298894-3405> +55(84)9447-7354 <%2B55%2884%299447-7354>

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217237545

jefperito commented 8 years ago

Acho válido a discussão sobre a divisão por módulos, já que a complexidade da biblioteca vem aumentando com as últimas features propostas/adicionadas.

waldandrade commented 8 years ago

Vamos iniciar a discussão pra valer?

https://github.com/wmixvideo/nfe/issues/136

2016-05-06 8:04 GMT-03:00 Jeferson Viana Perito notifications@github.com:

Acho válido a discussão sobre a divisão por módulos, já que a complexidade da biblioteca vem aumentando com as últimas features propostas/adicionadas.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-217412168

Waldney Souza de Andrade compengi engenharia & sistemas waldney.andrade@gmail.com waldney.andrade@gmail.com

+55(84)8894-3405 +55(84)9447-7354

fincatto commented 8 years ago

Pessoal, criei um branch para fazermos as adaptações necessárias e deixar a biblioteca independente de tipo de certificado: https://github.com/wmixvideo/nfe/tree/assinatura

Pelo que vi nos códigos enviados por vocês, a única coisa que percebi que realmente era alterado era o KeyStore. Então achei melhor alterarmos a classe de configuração da biblioteca para que a mesma retorne o KeyStore, e não mais o certificado (evitar fazer o tratamento em diversos lugares. Adicionei no README um exemplo de como carreguei os KeyStores (A1) aqui.

Infelizmente não tenho certificado A3 para testar, então só consigo testar o A1 e o resto eu conto com vocês.

Atenciosamente, Diego Fincatto

waldandrade commented 8 years ago

Boa tarde amigo .... não estou encontrado as alterações referentes ao certificado A3.

Alguém poderia me auxiliar, por que as classes que estão no master parecem ser as mesmas de antes .... a biblioteca de configuração deveria retornar o KeyStore pelo que tínhamos conversado. rs

caiocteodoro commented 8 years ago

olá @waldandrade

A branches https://github.com/wmixvideo/nfe/tree/assinatura contém essas alterações.

fincatto commented 8 years ago

Acabamos, sem querer, fechando o branch. Voltei ele e estou fazendo um merge do master pra ele. No início da tarde farei o commit derradeiro! Mas pode ir integrando e testando, modificações serão poucas. Atenciosamente,

On Fri, May 13, 2016 at 12:36 PM, caiocteodoro notifications@github.com wrote:

olá @waldandrade https://github.com/waldandrade

A branches https://github.com/wmixvideo/nfe/tree/assinatura contém essas alterações.

— You are receiving this because you were assigned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-219079198

waldandrade commented 8 years ago

ótimo .. obrigado @fincatto

waldandrade commented 8 years ago

boa tarde .. existe alguma possibilidade de incluir essa versão no Maven?

:)

fincatto commented 8 years ago

Sim. Provavelmente este final de semana eu lançarei a versão 1.2 e já subiremos pro maven. Att, Diego

On Tue, May 17, 2016 at 1:22 PM, waldandrade notifications@github.com wrote:

boa tarde .. existe alguma possibilidade de incluir essa versão no Maven?

:)

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/wmixvideo/nfe/issues/27#issuecomment-219772603

fincatto commented 8 years ago

Versão lançada, em breve já estará no maven. Att, Diego

MarioJunio commented 7 years ago

fincatto, comecei a estudar seu projeto e vou utilizar em uma aplicação web, que tem como pré requisito utilizar certificados A3, li os comentários acima, mas não consegui identificar a mudança que você fez no projeto para suportar os certificados A3, você poderia me ajudar, para que eu possa utilizar certificados A3 ?

lucasmoreiradev commented 7 years ago

@MarioJunio para suportar o uso de certificado A3, agora a API tem um método que recebe um arquivo XML já assinado e envia para a SEFAZ.

    /**
     * Faz o envio assinado para a Sefaz de NF-e e NFC-e
     * ATENCAO: Esse metodo deve ser utilizado para assinaturas A3
     *
     * @param loteAssinadoXml lote assinado no formato XML
     * @param modelo          modelo da nota (NF-e ou NFC-e)
     * @return dados do lote retornado pelo webservice
     * @throws Exception caso nao consiga gerar o xml ou problema de conexao com o sefaz
     */
    public NFLoteEnvioRetorno enviaLoteAssinado(final String loteAssinadoXml, final NFModelo modelo) throws Exception {
        return this.wsLoteEnvio.enviaLoteAssinado(loteAssinadoXml, modelo);
    }

Ou seja, você cria uma solução para assinar o XML com o certificado A3 e depois utiliza este método.

A solução para assinar o XML com certificado A3 independe da API. Cada um pode implementar de uma forma diferente.

MarioJunio commented 7 years ago

Entendi, mas tem outro problema também, que seria na criação da classe que herda de NFeConfig, pois essa classe necessita que você informe o certificado .pfx no método: public KeyStore getCertificadoKeyStore() throws KeyStoreException, e a senha do certificado no método: public String getCertificadoSenha()

Caso não seja informado é lançado uma exceção: java.security.KeyStoreException: Nao foi possibel montar o KeyStore com a cadeia de certificados

Como ficaria a implementação dessa classe, pois vou implementar uma aplicação web, que irá comunicar com uma aplicação desktop onde será assinado o xml e enviado ao servidor web novamente, com isso o certificado não será inicializado na aplicação web, como devo proceder contornar isso ?

lucasmoreiradev commented 7 years ago

@MarioJunio meu caso é o mesmo do seu. Tenho uma app web que é o NFe em si e uma desktop só pra assianar o XML.

Eu tenho 2 implementações de NFeConfig. Uma para o certificado A1 e outra para o certificado A3. A implementação do certificado A1 sempre retorna o certificado do cliente. Já a implementação para A3, retorna sempre o meu certificado A1, já que ele será utilizado apenas para abrir conexões SSL com a SEFAZ.

MarioJunio commented 7 years ago

Ah entendi, então a NFeConfig da aplicação web sempre usa seu certificado A1 como padrão, e um programa desktop usa por exemplo um certificado A3 que o cliente selecionou, e assassina os XML e retorna ao servidor, para enviar a SEFAZ né, mas isso não gera divergência não, pois você está utilizando um certificado A1 para abrir a conexão como WebService da SEFAZ e assinando o XML com a chave privada de outro certificado ?

Para a aplicação Desktop comunicar com o Web você usou Socket em tempo real, ou somente fica verificando em uma tabela temporária para ver se há XML a serem assinados, e depois de assinar devolve para essa tabela o XML assinado para a aplicação web consumir ?