android 實現https通訊,通過讀取cer或pfx證書

1. 通過pfx證書實現https請求

 準備好xxx.pfx證書(如放在assets目錄下)
 準好證書的私鑰密碼

代碼實現如下:

public static final String CLIENT_KET_PASSWORD="123456";
 KeyStore trustStore = KeyStore.getInstance("PKCS12", "BC");
            trustStore.load(MainActivity.this.getAssets().open("xxxx.pfx"), CLIENT_KET_PASSWORD.toCharArray());
            org.apache.http.conn.ssl.SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore, CLIENT_KET_PASSWORD.toCharArray());
            sf.setHostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, "utf-8");

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory
                    .getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            HttpClient client = null;
            String msg = "";
            try
            {
                ClientConnectionManager ccm =
                        new ThreadSafeClientConnManager(params, registry);
                client = new DefaultHttpClient(ccm, params);
                HttpGet hg = new HttpGet(url);
                HttpResponse response = client.execute(hg);
                HttpEntity entity = response.getEntity();
                if (entity != null)
                {
                    InputStream instreams = entity.getContent();
                    msg = convertStreamToString(instreams);
                }
                 Log.d("result",msg);
            }
            catch (Exception e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
   **並且需要自定義SSLSocketFactory類**

public class SSLSocketFactoryEx extends SSLSocketFactory
{
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public SSLSocketFactoryEx(KeyStore truststore, char[] arry)
            throws NoSuchAlgorithmException, KeyManagementException,
            KeyStoreException, UnrecoverableKeyException
    {
        super(truststore);
        KeyManagerFactory localKeyManagerFactory =
                KeyManagerFactory.getInstance(KeyManagerFactory
                        .getDefaultAlgorithm());
        localKeyManagerFactory.init(truststore, arry);
        KeyManager[] arrayOfKeyManager =
                localKeyManagerFactory.getKeyManagers();
        TrustManager tm = new X509TrustManager()
        {

            @Override
            public X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException
            {

            }

            @Override
            public void checkClientTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException
            {

            }
        };

        sslContext.init(arrayOfKeyManager, new TrustManager[] { tm },
                new java.security.SecureRandom());
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port,
                               boolean autoClose) throws IOException, UnknownHostException
    {
        return sslContext.getSocketFactory().createSocket(socket, host, port,
                autoClose);
    }

    @Override
    public Socket createSocket() throws IOException
    {
        return sslContext.getSocketFactory().createSocket();
    }
}

2.通過cer證書實現https請求

    /**
     * HttpsURLConnection 實現https請求
     */
    private void starHttpsCer(String urlStr) {
        HttpsURLConnection conn = null;
        try {
            URL url = new URL(urlStr);
            conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(setCertificates(MainActivity.this.getAssets().open("xxx.cer")));
            conn.connect();
            if(conn.getResponseCode() == 200) {
                InputStream is = conn.getInputStream();
                ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
                int ch;
                while ((ch = is.read()) != -1) {
                    bytestream.write(ch);
                }
                is.close();
                conn.disconnect();
                byte[] result = bytestream.toByteArray();
                Log.d("result",new String(result));
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

public SSLSocketFactory setCertificates(InputStream... certificates){
        try{
            //證書工廠。此處指明證書的類型
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            //創建一個證書庫
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates){
                String certificateAlias = Integer.toString(index++);
                //將證書導入證書庫
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

                try{
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e){
                    e.printStackTrace() ;
                }
            }

            //取得SSL的SSLContext實例
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.
                    getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);

//            //初始化keystore
//            KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
//            clientKeyStore.load(getAssets().open("client.jks"), "123456".toCharArray());
//
//            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
//            keyManagerFactory.init(clientKeyStore, "123456".toCharArray());

//            第一個參數是授權的密鑰管理器,用來授權驗證。TrustManager[]第二個是被授權的證書管理器,用來驗證服務器端的證書。第三個參數是一個隨機數值,可以填寫null
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
//            sslContext.init(null, null, new SecureRandom());
            return sslContext.getSocketFactory() ;


        } catch (Exception e){
            e.printStackTrace();
        }
        return null ;
    }

注:
如果手機上開了網絡代理,有可能遇上請求失敗,請關閉代理後重試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章