2016年5月25日 星期三

java implement http ssl client

因為案子需要,最近重寫了一下用 java 發 https request 的部份...

原則上不想匯入憑證認證,就是做一個怎樣都會通過的 TrustManager,丟進去。
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

若是出現 hostname 有問題時(大概就是發生在憑證的內容有對不上的,因為這次測試環境很差只能用自定,還開在奇怪的port上來用),就是裝死跳過 hostname 檢查
HttpsURLConnection.setDefaultHostnameVerifier(hv);

然後不知道是因為臨時湊了一個提供https 的server出來,內容不太穩定還是jdk的bug?(這環境的jdk非常老舊Orz),碰到 https 連線的 inputStream 的block 有點問題...(就是這個https的連線,居然沒辦法用 bufferedReader.ready() 抓到正確的分段,所以只好直接用bufferedReader.readLine() 硬上了XD)

總之會動就好一.一|||


        String xml = "";
       
        if(StringUtils.isEmpty(urlPath))  {
            return xml;
        }
       
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            }
            public boolean isServerTrusted(java.security.cert.X509Certificate[] certs)  {
                return true;
            }
            public boolean isClientTrusted(java.security.cert.X509Certificate[] certs)  {
                return true;
            }
        } };
       
        // Install the all-trusting trust manager
        try {
            // hostname verify
            HostnameVerifier hv = new HostnameVerifier()  {
                public boolean verify(String urlHostName, SSLSession session)  {
                    //no verify hostname...
                    return true;
                }
            };
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
        } catch (Exception e3) { }
       
        BufferedReader br = null;
        InputStreamReader in = null;
       
        String str = "";
        try {
            URL url = new URL(urlPath);
            URLConnection urlConn = url.openConnection();
            urlConn.setUseCaches(false);
           
            in = new InputStreamReader(urlConn.getInputStream());
            br = new BufferedReader(in);
            //not use br.ready()...in this case, br.ready is always false?!
            while(null != (str=br.readLine() ))  {
                if(str.length() > 0)  {
                    xml += str+"\n";
                }
            }
            System.out.println(xml);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(br != null) {try  {br.close();}  catch(Exception ee){}}
            if(in != null) {try  {in.close();}  catch(Exception ee){}}
        }
       
        return xml;

沒有留言: