2010-07-30 105 views

回答

21

下面是一些代码,让你去。 KeyStore是包含客户端证书的对象。如果服务器正在使用自签名证书或由JVM在附带的cacerts文件中识别的未由CA签名的证书,那么您将需要使用TrustStore。否则使用默认cacerts文件,在传递到nullSSLSockeFactory信任存储参数..

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

谢谢。我会很快检查出来的。 – hooknc 2010-07-30 22:10:41

+0

此解决方案完美工作。谢谢您的帮助。 仅供参考,由于SSL握手重新谈判的问题,我不得不设置以下虚拟机属性: -Dsun.security.ssl.allowUnsafeRenegotiation =真 我/是与Java 1.6.0_20和Tomcat 6.0.29工作。 – hooknc 2010-08-18 16:52:01

+2

使用jdk 1.6.0_24或更高版本时,不再需要上述注释。 – hooknc 2011-04-05 15:43:49

2

另一种解决方案(从另一示例复制)。我使用了'trusting'(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

我从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(); 
    } 
} 
+0

链接到源将是有益的... – 2015-01-08 01:07:47

+1

@EvilRaat http://hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java从http:// HC .apache.org/httpcomponents-客户版本4.3.x/examples.html – EpicPandaForce 2015-01-08 09:04:04