Garmaine Staff asked 1 year ago

In my desktop java application there is a class that connects with other system through HTTPS connection using a client certificate. Part of this connection is the SSLContext which receives the KeyManager[] and the TrustManager[] in order to implement the user certificate and the trsut store to get the handshack with the remote server. This class uses the Windows repository to get the list of certificates available on the machine so the user can pick the right one to connect. The problem is that I'm migrating this application to a cloud web server (tomcat) and the procedute to get the certificate is quite different. With tomcat I'm able to forward the user to a https page that requests a valid certificate issued by a CA. Once the user access this page, the browser pops up a window with the certificates available on the machine, so the user can pick one authenticate. My problem now is to create this SSLContext once, from the browser authentication, I can get only the x509 cert selected by the user, but without the Private Key. My question is. Am I missing something to get the certificate Private Key? I know that windows repository does not share the private key, but when this procedure is called from a desktop application, at least the "resume or header" (RSAPrivateKey[size = 2048 bits, type = Exchange, container = {########}) of the key is provided, which still works. But through the browser, I cannot get this information. Or is there another way to create the KeyManager[] with just the x509 certificate without provide the private key?

here is a piece of the code which creates the connection with the server..

// create the connection
SocketFactoryDinamico socketFactory = new SocketFactoryDinamico(X509certificate, PrivateKey);
socketFactory.setFileCacerts(getClass().getResourceAsStream("cacerts"));

KeyManager[] keyManagers = socketFactory.createKeyManagers();
TrustManager[] trustManagers = socketFactory.createTrustManagers();

SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(keyManagers, trustManagers, null);

HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());

String url = "https://someserver.com";

URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

and here is the code which gets the x509 certificate on the .jsp…

X509Certificate[] certs = (X509Certificate[]) 
request.getAttribute("javax.servlet.request.X509Certificate");
if (null != certs && certs.length > 0) {

    X509Certificate cert = certs[0];
}

and here is the server configuration to request the certificate authentication

<Connector
    clientAuth="true" 
    port="8443" 
    protocol="HTTP/1.1" 
    SSLEnabled="true"
    scheme="https" 
    secure="true"
    keystoreFile="C:/JavaWeb/tomcat"
    keystoreType="JKS" keystorePass="pswd"
    truststoreFile="C:/JavaWeb/myTrustStore"
    truststoreType="JKS" truststorePass="changeit"
    SSLVerifyCLient="require" SSLVerifyDepth="10" sslProtocol="TLS"
/>