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