Mutual Authentication with x509 Certificates using HttpClient 4.0.1

后端 未结 3 1500
旧时难觅i
旧时难觅i 2020-12-14 03:35

Does anyone have any friendly tips on how to perform client authentication via an x509 certificate using HTTPClient 4.0.1?

相关标签:
3条回答
  • 2020-12-14 04:11

    I used the following from a sample code on HttpClient's website (custom SSL context if I remember correctly).

    {
        KeyStore keyStore = KeyStore.getInstance("PKCS12"); //client certificate holder
        FileInputStream instream = new FileInputStream(new File(
                "client-p12-keystore.p12"));
        try {
            trustStore.load(instream, "password".toCharArray());
        } finally {
            instream.close();
        }
    
        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, "password".toCharArray())
                // .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) //if you have a trust store
                .build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext, new String[] { "TLSv1" }, null,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients
                .custom()
                .setHostnameVerifier(
                        SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) //todo
                .setSSLSocketFactory(sslsf).build();
        try {
    
            HttpGet httpget = new HttpGet("https://localhost:8443/secure/index");
    
            System.out.println("executing request" + httpget.getRequestLine());
    
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();
    
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                if (entity != null) {
                    System.out.println("Response content length: "
                            + entity.getContentLength());
                }
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
    
    0 讨论(0)
  • 2020-12-14 04:13

    Another solution (copied from another example). I've used the same keystore for both 'trusting' (trustStore) and for authenticate myself (keyStore).

     KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
     FileInputStream instream = new FileInputStream(new File("miller.keystore"));
     try {
         trustStore.load(instream, "pw".toCharArray());
     } finally {
         instream.close();
     }
    
     SSLContext sslcontext = SSLContexts.custom()
             .loadTrustMaterial(trustStore) /* this key store must contain the certs needed & trusted to verify the servers cert */
             .loadKeyMaterial(trustStore, "pw".toCharArray()) /* this keystore must contain the key/cert of the client */
             .build();
    
     SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
             SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
     CloseableHttpClient httpclient = HttpClients.custom()
             .setSSLSocketFactory(sslsf)
             .build();
     try {
    
         HttpGet httpget = new HttpGet("https://localhost");
    
         System.out.println("executing request" + httpget.getRequestLine());
    
         CloseableHttpResponse response = httpclient.execute(httpget);
         try {
             HttpEntity entity = response.getEntity();
    
             System.out.println("----------------------------------------");
             System.out.println(response.getStatusLine());
             if (entity != null) {
                 System.out.println("Response content length: " + entity.getContentLength());
             }
             EntityUtils.consume(entity);
         } finally {
             response.close();
         }
     } finally {
         httpclient.close();
     }
    
    0 讨论(0)
  • 2020-12-14 04:36

    Here is some code to get you going. The KeyStore is the object that contains the client certificate. If the server is using a self-signed certificate or a certificate that isn't signed by a CA as recognized by the JVM in the included cacerts file then you will need to use a TrustStore. Otherwise to use the default cacerts file, pass in null to SSLSockeFactory for the truststore argument..

    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
    import org.apache.http.params.BasicHttpParams;
    import org.apache.http.params.HttpParams;
    
    ...
    
    final HttpParams httpParams = new BasicHttpParams();
    
    // load the keystore containing the client certificate - keystore type is probably jks or pkcs12
    final KeyStore keystore = KeyStore.getInstance("pkcs12");
    InputStream keystoreInput = null;
    // TODO get the keystore as an InputStream from somewhere
    keystore.load(keystoreInput, "keystorepassword".toCharArray());
    
    // load the trustore, leave it null to rely on cacerts distributed with the JVM - truststore type is probably jks or pkcs12
    KeyStore truststore = KeyStore.getInstance("pkcs12");
    InputStream truststoreInput = null;
    // TODO get the trustore as an InputStream from somewhere
    truststore.load(truststoreInput, "truststorepassword".toCharArray());
    
    final SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("https", new SSLSocketFactory(keystore, keystorePassword, truststore), 443));
    
    final DefaultHttpClient httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, schemeRegistry), httpParams);
    
    0 讨论(0)
提交回复
热议问题