2
respostas

Como trocar o truststore dinamicamente em tempo de execução e fazer com que a mudança tenha efeito imediato?

Prezados,

Estou com um problema com a troca da truststore em tempo de execução para estabelecer um nova conexão HTTPS. Ocorre que uma aplicação do governo exige que o certificado A1 (e-CNPJ), utilizado para estabelecer a conexão com o servidor do governo, seja o mesmo utilizado para assinar digitalmente o arquivo XML que será transmitido (payload). No lado da aplicação da empresa a sua base de dados é multi-empresas, o que faz com que seja feito o envio de payloads provenientes de diferentes CNPJs. Cada CNPJ tem o seu certificado A1 que é utilizado para assinar o payload e para, em seguida, estabelecer a conexão segura com o servidor do governos para envio.

A aplicação é desenvolvida em J2EE, onde a mesma é implantada no servidor de aplicação WildFly 10.1.0, rodando em CentOS 7.

Segue o trecho do código onde a configuração do certificado A1 é configurado, antes de estabelecer a conexão, via HTTPS, com servidor do governo para consumo do web service:

    public HandShake configForHandshake(final Path keyStore, final String keyStorePassword, final Path trustStore, final String trustStorePassword) {
        validateStoreInfo(keyStore, trustStore);
        LOGGER.info("Configuring handshake - init");

        System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
        System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
        System.setProperty("javax.net.ssl.trustStoreType", "JKS");
        System.setProperty("javax.net.ssl.trustStore", trustStore.toAbsolutePath().toString());
        System.setProperty("javax.net.ssl.trustPassword", trustStorePassword == null ? "" : trustStorePassword);

        System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
        System.setProperty("javax.net.ssl.keyStore", keyStore.toAbsolutePath().toString());
        System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword == null ? "" : keyStorePassword);

        if (LOGGER.isDebugEnabled()) {
            // Referência:
            //  https://access.redhat.com/documentation/en-US/Fuse_MQ_Enterprise/7.1/html/Security_Guide/files/SSL-Tutorial.html
            System.setProperty("javax.net.debug", "ssl");
        }

        LOGGER.info("Configuring handshake - end");
        return new HandShake(keyStore, keyStorePassword, trustStore, trustStorePassword);
    }

Da forma como está feito, o primeiro CNPJ que faz a conexão com o servidor do governo, é recuperado o seu respectivo certifica A1 (e-CNPJ). Enquanto as chamadas subsequentes do web service forem do mesmo certificado, o sistema do governo aceita o payload. Entretanto, quando muda o CNPJ, o seu certificado A1 é recuperado, é feita a configuração para handshake com o certificado recém recuperado e feita a chamada do web service. Nesse momento, o payload é enviado com sucesso, entretanto é executada uma regra de negócio do governo que verifica se o CNPJ do certificado A1 é o mesmo do payload recebido. Essa regra de negócio rejeita o payload, informando que o seu CNPJ é diferente do certificado A1 utilizado para fazer a transmissão.

Dito isso, estou procurando encontrar uma maneira de resolver o problema, pois a forma que é definido o certificado A1, me parece que fica em memória o certificado da primeira conexão. As chamadas subsequentes o certificado não é alterado, mesmo com a execução do trecho do código apresentado.

Eu já revisei o arquivo PFX, antes do envio da chamada do web service do governo, e ele está em conformidade com o CNPJ do payload que será transmitido, só para garantir que não há qualquer erro na lógica de busca do certificado A1 associado ao CNPJ.

Um teste que fiz, foi o seguinte: Transmiti um payload do CNPJ1, o qual foi aceito sem erros pela aplicação do governo. Logo em seguida, fiz a transmissão do payload do CNPJ2. Daí ocorre o erro de validação da regra de negócio do governo. Após isso, fiz um shutdown/startup do WildFly e transmiti novamente o payload do CNPJ2, que, dessa vez, é aceito sem erros pela aplicação do governo. Logo em seguida, fiz a transmissão do payload do CNPJ1. Agora, ocorre erro de validação da regra de negócio do governo para o CNPJ1. Dessa forma, pude comprovar que o certificado utilizado para transmissão é sempre o da primeira transmissão realizada pela aplicação que desenvolvo.

Alguém poderia me ajudar com essa questão: Como trocar o truststore dinamicamente em tempo de execução e fazer com que a mudança tenha efeito imediato?

Desde já, agradeço a atenção! Anderson Bestteti

2 respostas

Olha, acho que você domina mais esse assunto que eu :). De todo jeito, me esmerei com o amigo google e achei esse link => https://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/

É antigo, mas parece que ele lida com um problema similar ao seu. Ele cria uma implementação dele do X509TrustManager para que seja possível recarregar os certificados entre chamadas, pelo menos foi isso que eu entendi. Tomara que seja útil.

Olá Alberto,

Em primeiro lugar, muito obrigado pelo retorno e indicação do link. Eu acabei encontrando o mesmo artigo ontem no final da tarde, mas ainda não parei para analisar se a solução apresentada serve para o meu propósito. Eu vou avaliar o código e fazer testes na minha aplicação para ver se ela se aplica ao meu caso. Assim que eu tiver um resultado eu vou atualizar aqui. Certo?

Obrigado, mais uma vez.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software