Tenho uma situação onde meu sistema se conecta ao Sefaz utilizando um certificado A1. Para tratar os certificados, tenho a classe SocketFactoryDinamico. O que ocorre é que através do Proxy, não não consigo sucesso na conexão. Recebo a seguinte mensagem: “javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?”
Se eu fizer a conexão sem utilizar SocketFactoryDinamico, setando os parâmetros na JVM (conforme abaixo) funciona. Mas dessa forma não atende.
private void a1Certification() {
System.setProperty(“java.protocol.handler.pkgs”, “com.sun.net.ssl.internal.www.protocol”);
System.setProperty(“javax.net.ssl.keyStoreType”, SecuredConnection.PKCS12);
System.clearProperty("javax.net.ssl.keyStore");
System.clearProperty("javax.net.ssl.keyStorePassword");
System.clearProperty("javax.net.ssl.trustStore");
System.setProperty("javax.net.ssl.keyStore", this.config.getCertConfig().getA1Config().getKeystorePath());
System.setProperty("javax.net.ssl.keyStorePassword", this.config.getCertConfig().getA1Config().getKeystorePin());
System.setProperty("javax.net.ssl.trustStoreType", SecuredConnection.JKS);
System.setProperty("javax.net.ssl.trustStore", this.config.getCertConfig().getCacertsPath());
}
Segue minha classe SocketFactoryDinamico:
import java.io.IOException;
import java.io.InputStream;
import java.net.;
import java.security.;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.SocketFactory;
import javax.net.ssl.*;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SocketFactoryDinamico implements ProtocolSocketFactory {
private static final Logger LOG = LoggerFactory.getLogger(SocketFactoryDinamico.class);
private SSLContext ssl = null;
private final X509Certificate certificate;
private final PrivateKey privateKey;
private InputStream fileCacerts;
public SocketFactoryDinamico(X509Certificate certificate,
PrivateKey privateKey) {
this.certificate = certificate;
this.privateKey = privateKey;
}
private SSLContext createSSLContext() {
try {
KeyManager[] keyManagers = createKeyManagers();
TrustManager[] trustManagers = createTrustManagers();
SSLContext sslContext = SSLContext.getInstance( "TLSv1");
sslContext.init(keyManagers, trustManagers, null);
return sslContext;
} catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
LOG.info(e.toString());
}
return null;
}
private SSLContext getSSLContext() {
if (ssl == null) {
ssl = createSSLContext();
}
return ssl;
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress,
int localPort, HttpConnectionParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress,
localPort);
}
Socket socket = socketfactory.createSocket();
((SSLSocket) socket).setEnabledProtocols(new String[] {"SSLv3", "TLSv1"});
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
System.out.println(localaddr.toString());
System.out.println(remoteaddr.toString());
socket.bind(localaddr);
try {
System.out.println(socket.getRemoteSocketAddress());
socket.connect(remoteaddr, timeout);
} catch (Exception e) {
LOG.info(e.toString());
throw new ConnectTimeoutException("Possível timeout de conexão", e);
}
return socket;
}
@Override
public Socket createSocket(String host, int port, InetAddress clientHost,
int clientPort) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(host, port,
clientHost, clientPort);
}
@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(host, port);
}
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host,
port, autoClose);
}
public KeyManager[] createKeyManagers() {
HSKeyManager keyManager = new HSKeyManager(certificate, privateKey);
return new KeyManager[] { keyManager };
}
public TrustManager[] createTrustManagers() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(fileCacerts, "changeit".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
return trustManagerFactory.getTrustManagers();
}
class HSKeyManager implements X509KeyManager {
private final X509Certificate certificate;
private final PrivateKey privateKey;
public HSKeyManager(X509Certificate certificate, PrivateKey privateKey) {
this.certificate = certificate;
this.privateKey = privateKey;
}
@Override
public String chooseClientAlias(String[] arg0, Principal[] arg1,
Socket arg2) {
return certificate.getIssuerDN().getName();
}
@Override
public String chooseServerAlias(String arg0, Principal[] arg1,
Socket arg2) {
return null;
}
@Override
public X509Certificate[] getCertificateChain(String arg0) {
return new X509Certificate[] { certificate };
}
@Override
public String[] getClientAliases(String arg0, Principal[] arg1) {
return new String[] { certificate.getIssuerDN().getName() };
}
@Override
public PrivateKey getPrivateKey(String arg0) {
return privateKey;
}
@Override
public String[] getServerAliases(String arg0, Principal[] arg1) {
return null;
}
}
public void setFileCacerts(InputStream fileCacerts) {
this.fileCacerts = fileCacerts;
}
}