日期:2014-05-20  浏览次数:20858 次

咨询一个httpclient SSL 双向认证的问题
我用httpClient来访问一些网站截取数据,

普通的SSL网站我用下面这个类来自动接受所有的SSL证书,可以满足我的使用
Java code


DefaultHttpClient df = new DefaultHttpClient();

httpclient = WebClientDevWrapper.wrapClient(httpclient); 

//这样子我就几乎能访问所有的https网站了。

    public static DefaultHttpClient wrapClient(HttpClient base) { 
        try { 
            SSLContext ctx = SSLContext.getInstance("TLS"); 
            X509TrustManager tm = new X509TrustManager() { 

                //public X509Certificate[] getAcceptedIssuers() { 
                public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
                    return null; 
                }

                @Override
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] chain,
                        String authType) throws CertificateException {
                    // TODO Auto-generated method stub
                    
                }

                @Override
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] chain,
                        String authType) throws CertificateException {
                    // TODO Auto-generated method stub                    
                }
            }; 
            ctx.init(null, new TrustManager[]{tm}, null); 
            SSLSocketFactory ssf = new SSLSocketFactory(ctx); 
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
            ClientConnectionManager ccm = base.getConnectionManager(); 
            SchemeRegistry sr = ccm.getSchemeRegistry(); 
            sr.register(new Scheme("https", ssf, 443)); 
            return new DefaultHttpClient(ccm, base.getParams()); 
        } catch (Exception ex) { 
            ex.printStackTrace(); 
            return null; 
        } 



但现在有一个网站,他是须要双向认证的,就像银行网银一样,
我在httpClient的示例里面找到这么个代码,
现在的问题是,用下面的示例代码显示javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated错误

我认为是程序怀疑服务器证书不安全,所以抛出了这个错误
现在我想让程序即能自动接受所有的服务器端不安全证书,又能发送客户端证书,
也就是把上面和下面的代码结合在一起,应该怎么做?

Java code

    public final static void main(String[] args) throws Exception {
        DefaultHttpClient httpclient = new DefaultHttpClient();

        KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());        
        FileInputStream instream = new FileInputStream(new File("my.keystore")); 
        try {
            trustStore.load(instream, "nopassword".toCharArray());
        } finally {
            instream.close();
        }
        
        SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
        Scheme sch = new Scheme("https", socketFactory, 443);
        httpclient.getConnectionManager().getSchemeRegistry().register(sch);

        HttpGet httpget = new HttpGet("https://localhost/");

        System.out.println("executing request" + httpget.getRequestLine());
        
        HttpResponse response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();

        System.out.println("----------------------------------------");
        System.out.println(response.getStatusLine());
        if (entity != null) {
            System.out.println("Response content length: " + entity.getContentLength());
        }
        if (entity != null) {
            entity.consumeContent();
        }

        // When HttpClient instance is no longer needed, 
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();        
    }




------解决方案--------------------