我用工商银行提供的商户pfx格式证书可以通过浏览器与https://corporbank.icbc.com.cn/servlet/ICBCINBSEBusinessServlet建立连接并按照指定格式提交表单得到返回数据,但用java编写时SSLSocket却无法握手成功,我把pfx导入到浏览器再导出成cer,然后用keytool导入到一个生成的证书库tomcat.keystore中,但通过以下代码却无法成功,host是我ping corporbank.icbc.com.cn得来的。请各位高手指点迷津。               
   //server socket's ip and port
     //https://corporbank.icbc.com.cn/servlet/ICBCINBSEBusinessServlet
        String host="60.247.99.4";
        int port=80;
        
        //keystore path and password
        String keystore = "D:\\tomcat.keystore";
        
        String pass="12345678";
        //set up a connection
        SSLSocketFactory ssf=null;
        try
        {
            //init context
            SSLContext ctx=SSLContext.getInstance("TLS");            
            KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
            TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509");            
            KeyStore ks=KeyStore.getInstance("JKS");
            KeyStore tks=KeyStore.getInstance("JKS");
            //load keystore
            ks.load(new FileInputStream(keystore),pass.toCharArray());
            tks.load(new FileInputStream(keystore),pass.toCharArray());
            
            kmf.init(ks,pass.toCharArray());
            tmf.init(tks);
            ctx.init(kmf.getKeyManagers(),tmf.getTrustManagers(),new SecureRandom());
            System.out.println("load keystore success.");
            ssf=ctx.getSocketFactory();
            //create socket
            socket=(SSLSocket)ssf.createSocket(host,port);
            System.out.println("create socket success.");
            socket.setSoTimeout(3000);
            
            String[] protocols = socket.getEnabledProtocols();
            
            for (int i = 0; i < protocols.length; i++) {
System.out.println(protocols[i]);
}
            
            socket.setEnabledProtocols(new String[]{"TLSv1"});             //handshake 总是在这里报Read timed out
            socket.startHandshake();
            System.out.println("handshake success.");
        }catch(Exception e)
        {
            System.out.println("establish connection error.");
            e.printStackTrace();
            return;
        }

解决方案 »

  1.   

    自己参考别人的搞定了,由于服务器端证书验证失败,所有信任所有证书^o^。 /**
         * 所有主机默认通过
         */
    private static HostnameVerifier hnv = new HostnameVerifier() {
           public boolean verify(String hostname, SSLSession session) {
            return true;
           }
       };
       /**
        * 关键在这信任所有证书
        */    
           private static TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        return;
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        return;
                    }
                }//X509TrustManager
       };//TrustManager[]String keyf="F:\\test.pfx";
            
            String pass="12345678";
            //set up a connection
            SSLSocketFactory ssf=null;     PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try
        {
                //init context
                SSLContext ctx=SSLContext.getInstance("TLS");            
                KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
                TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509");            
                KeyStore ks=KeyStore.getInstance("PKCS12");             //load keystore
                ks.load(new FileInputStream(keyf),pass.toCharArray());
                
                kmf.init(ks,pass.toCharArray());
                
                ctx.init(kmf.getKeyManagers(),trustAllCerts,null);
                
                System.out.println("load keystore success.");
                ssf=ctx.getSocketFactory();
                
                HttpsURLConnection.setDefaultSSLSocketFactory(ssf);             HttpsURLConnection.setDefaultHostnameVerifier(hnv);
                
        URL realUrl = new URL(url);
        
        //打开和URL之间的连接
        HttpsURLConnection conn = (HttpsURLConnection) realUrl.openConnection();     //设置通用的请求属性
        conn.setRequestProperty("accept", "*/*"); 
        conn.setRequestProperty("connection", "Keep-Alive"); 
        conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); 
        
        //发送POST请求必须设置如下两行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        //获取URLConnection对象对应的输出流
        out = new PrintWriter(conn.getOutputStream());
        //发送请求参数
        out.print(param);
        //flush输出流的缓冲
        out.flush();
        //定义BufferedReader输入流来读取URL的响应
        in = new BufferedReader(
        new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = in.readLine())!= null)
        {
         result += "\n" + line;
        }
        }
        catch(Exception e)
        {
         System.out.println("发送POST请求出现异常!" + e);
         e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally
        {
        try
        {
         if (out != null)
         {
         out.close();
         }
        if (in != null)
        {
         in.close();
        }
        }
        catch (IOException ex)
        {
         ex.printStackTrace();
        }
        }
      

  2.   


     这段代码我见过,但是好象不是webform的写法?
      

  3.   

    那不是可以开发出来黑别人的money?
      

  4.   

    http://www.163.com