android中使用https是否對服務憑證合法性校正的新的體會

來源:互聯網
上載者:User

標籤:目錄   ict   解析   inpu   校正   gets   getname   col   length   

package com.cetcs.logreport.utils;import android.content.Context;import org.apache.http.conn.ssl.SSLSocketFactory;import java.io.BufferedInputStream;import java.io.IOException;import java.io.InputStream;import java.net.Socket;import java.net.UnknownHostException;import java.security.InvalidKeyException;import java.security.KeyStore;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.SignatureException;import java.security.cert.CertificateException;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;/** *  * 解析伺服器憑證的類,對伺服器端的認證serv.crt進行解析,其中server.crt檔案是使用 * openssl產生的自簽名的認證* */public class SSLVerifyLogServerCrtSocketFactory extends SSLSocketFactory {    private static final String TAG = "SSLTrustAllSocketFactory";    private SSLContext mCtx;    private  Context context;    public SSLVerifyLogServerCrtSocketFactory(String crtName, KeyStore truststore, Context context)            throws Throwable {        super(truststore);        this.context = context;        try {            InputStream certInputStream = new BufferedInputStream(context.getAssets().open(crtName));            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");            final X509Certificate serverCertificate = (X509Certificate) certificateFactory.generateCertificate(certInputStream);            mCtx = SSLContext.getInstance("TLS");            mCtx.init(null, new TrustManager[]{new X509TrustManager() {                        @Override                        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {                        }                        @Override                        public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {                            if(x509Certificates == null){                                throw  new IllegalArgumentException("checkServerTrusted x509Certificates is null ");                            }                            if(x509Certificates.length < 0){                                throw  new IllegalArgumentException("checkServerTrusted x509Certificates is null ");                            }                            for(X509Certificate cert :x509Certificates){                                cert.checkValidity();                                try {                                    cert.verify(serverCertificate.getPublicKey());                                } catch (NoSuchAlgorithmException e) {                                    e.printStackTrace();                                } catch (InvalidKeyException e) {                                    e.printStackTrace();                                } catch (NoSuchProviderException e) {                                    e.printStackTrace();                                } catch (SignatureException e) {                                    e.printStackTrace();                                }                            }                        }                        @Override                        public X509Certificate[] getAcceptedIssuers() {                            return new X509Certificate[0];                        }                    }},                    null);        } catch (Exception ex) {        }    }    @Override    public Socket createSocket(Socket socket, String host,                               int port, boolean autoClose)            throws IOException, UnknownHostException {        return mCtx.getSocketFactory().createSocket(socket, host, port, autoClose);    }    @Override    public Socket createSocket() throws IOException {        return mCtx.getSocketFactory().createSocket();    }    //第一個參數是伺服器憑證的名字例如:server.crt,第二個參數是應用的上下文    public static SSLSocketFactory getSocketFactory( String crtName,Context context) {        try {            if(crtName == null || "".equalsIgnoreCase(crtName)){                throw  new IllegalArgumentException(" getSocketFactory crtName is null");            }            if(context == null){                throw  new IllegalArgumentException(" getSocketFactory context is null");            }            InputStream certInputStream = new BufferedInputStream(context.getAssets().open(crtName));            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");            X509Certificate serverCertificate = (X509Certificate) certificateFactory.generateCertificate(certInputStream);            //產生一個保護伺服器憑證的keystore            String keyStoreType = KeyStore.getDefaultType();            KeyStore keyStore = KeyStore.getInstance(keyStoreType);            keyStore.load(null, null);            String alias = serverCertificate.getSubjectX500Principal().getName();            keyStore.setCertificateEntry(alias, serverCertificate);            //產生SSLSocketFactory            SSLSocketFactory factory = new SSLVerifyLogServerCrtSocketFactory(crtName,keyStore,context);            return factory;        } catch (Throwable e) {            e.printStackTrace();        }        return null;    }}

需求使用:實現用戶端對伺服器的校正,需要證明伺服器認證的合法性,當https在握手的協議中返回給用戶端的認證應該和儲存在用戶端本地的認證解析出來的網域名稱應該一樣,說明伺服器返回的認證給保證在本地的認證是一樣的,說明伺服器是合法的

        try {            String crtName = "server.crt";            SSLSocketFactory sf = SSLVerifyLogServerCrtSocketFactory.getSocketFactory(crtName, mContext);            //對主機的有效網域名稱進行嚴格校正            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);return new DefaultHttpClient(ccm, params);

 其中server.crt就是儲存在手機app 例如assert目錄下的認證,是app本地保證的認證,這個認證必須和配置到後台例如tomacat伺服器中的認證是一模一樣,這裡為了用戶端驗證伺服器憑證的合法性,在手機app用戶端儲存了一個認證

 

mContext是activity或者context對應的手機的上下文,如果這裡用戶端和伺服器在建立https的過程中,如果伺服器返回給用戶端的認證的網域名稱和app本地儲存的認證解析出來的網域名稱是一樣的,說明伺服器是合法的。

如果用戶端在和伺服器建立https協議的時候,不對伺服器的合法性做校正,信任所有的伺服器
package com.cetcs.logreport.utils;/** * Created by wei.yuan on 2016/8/2. * * 該類主要是用於對伺服器憑證的單項驗證 */import org.apache.http.conn.ssl.SSLSocketFactory;import java.io.IOException;import java.lang.reflect.Field;import java.net.InetAddress;import java.net.Socket;import java.net.UnknownHostException;import java.security.KeyManagementException;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.UnrecoverableKeyException;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;public class SSLSocketFactoryEx extends SSLSocketFactory {    SSLContext sslContext = SSLContext.getInstance("TLS");    public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException,            KeyManagementException, KeyStoreException, UnrecoverableKeyException {        super(truststore);        // set up a TrustManager that trusts everything        TrustManager tm = new X509TrustManager() {            public X509Certificate[] getAcceptedIssuers() {                //return new X509Certificate[]{};                return null;            }            @Override            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {                // TODO Auto-generated method stub            }            @Override            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {                // TODO Auto-generated method stub            }        };        sslContext.init(null, new TrustManager[] { tm }, new java.security.SecureRandom());    }    @Override    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)            throws IOException, UnknownHostException {        injectHostname(socket, host);        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);    }    @Override    public Socket createSocket() throws IOException {        return sslContext.getSocketFactory().createSocket();    }    private void injectHostname(Socket socket, String host) {        try {            Field field = InetAddress.class.getDeclaredField("hostName");            field.setAccessible(true);            field.set(socket.getInetAddress(), host);        } catch (Exception ignored) {        }    }}

 

提示:
   KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());            trustStore.load(null, null);            SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

 

這樣大體就是一個使用心得

android中使用https是否對服務憑證合法性校正的新的體會

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.