Взаимная аутентификация с сертификатами x509 с использованием HttpClient 4.0.1 - PullRequest
12 голосов
/ 31 июля 2010

У кого-нибудь есть дружеские советы о том, как выполнить аутентификацию клиента с помощью сертификата x509 с использованием HTTPClient 4.0.1?

Спасибо за ваше время.

Ответы [ 3 ]

21 голосов
/ 31 июля 2010

Вот код, который поможет вам. KeyStore - это объект, который содержит сертификат клиента. Если сервер использует самозаверяющий сертификат или сертификат, который не подписан центром сертификации, как это распознает JVM во включенном файле cacerts, вам нужно будет использовать TrustStore. В противном случае, чтобы использовать файл cacerts по умолчанию, передайте от null до SSLSockeFactory для аргумента склада доверенных сертификатов ..

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);
2 голосов
/ 06 ноября 2013

Другое решение (скопировано из другого примера).Я использовал одно и то же хранилище ключей как для «доверия» (trustStore), так и для аутентификации себя (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 голосов
/ 10 ноября 2014

Я использовал следующее из примера кода на веб-сайте HttpClient (пользовательский контекст SSL, если я правильно помню).

{
    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();
    }
}
...