1. 程式人生 > >Https雙向認證Android客戶端配置

Https雙向認證Android客戶端配置

Https雙向認證啊  做了兩遍,第一遍懵懂狀態處於 好不容易做好了,換伺服器,一下子懵了,使出渾身解數又找了一遍,這下終於好了  快哭啦快哭了,必須滴要記錄一下,以免以後遇到繼續懵,這裡用retrofit2+okhttp3為例子來簡單說明下

先來說說證書:

服務端提供的證書有四個(我這裡四個就夠用了,有的上面介紹說有一個p12證書,原來提供過,表示沒用到,可能是我用的驗證方法不一樣吧)

轉化步驟:

1)生成客戶端證書

keytool -genkeypair -alias client -keyalg RSA -validity 3650 -keypass123456 -storepass 123456 -keystore client.jks

這裡要說一下,client.jks後端的同事已經提供給我,這一步我就省啦,如果沒提供的話 走一步就行啦

2)生成服務端keystore

keytool -genkeypair -alias server -keyalg RSA -validity 3650 -keypass 123456 -storepass123456 -keystore server.keystore

這個也提供啦,我也省了哈

3)匯出客戶端證書
keytool -export -alias client -file client.cer -keystore client.jks -storepass 123456

這裡根據本人理解是將客戶端的jks證書匯入到服務端cer證書中

4)匯出服務端證書
keytool -export -alias server -file server.cer -keystore server.keystore -storepass 123456

這裡本人理解是將cer證書匯入到keystore中(這裡感覺理解的不是很透徹,勿噴)

5)證書交換
將客戶端證書匯入服務端keystore中,再將服務端證書匯入客戶端keystore中, 一個keystore可以匯入多個證書,生成證書列表。
生成客戶端信任證書庫(由服務端證書生成的證書庫):
    keytool -import -v -alias server -file  server.cer -keystore truststore.jks -storepass 123456

將客戶端證書匯入到伺服器證書庫(使得伺服器信任客戶端證書):
keytool -import -v -alias client -file client.cer -keystore server.keystore -storepass 123456

6)轉換jks證書為Android能夠識別的BKS證書

將client.jks和truststore.jks通過portecle-1.9軟體轉換為.bks檔案

步驟:開啟portecle.jar檔案(window系統的,直接開啟是壓縮包哦,要選擇開啟方式 用java方式開啟,或者直接切換到mac系統轉換好了再貼上回來即可)

注意:我這裡轉換client.jks的時候回報錯的哦

java.security.KeyStoreException: java.io.IOException: Error initialising store of key store: java.security.InvalidKeyException: Illegal key size 這個尚未明白什麼意思,就換了一個方法生成client.bks檔案了 7)生成客戶端bks檔案
keytool -importcert -trustcacerts -keystore E:\newkey\client.bks -file E:\keyhttps\server.cer -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider 這個要在JDK目錄下:C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext中新增bcprov-ext-jdk15on-146.jar包檔案(這個根據不同的jdk版本找對應的,這個搜一下就行啦) 8)將client.bks,truststore.bks,以及server.cercopy到工程的Assets下完成驗證 9)專案中的配置 Application檔案
import android.app.Application;
import android.os.Environment;
import android.os.Process;
import android.util.Log;

import com.baidu.mapapi.SDKInitializer;
import com.franmontiel.persistentcookiejar.ClearableCookieJar;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.https.HttpsUtils;
import com.zhy.http.okhttp.log.LoggerInterceptor;

import org.wlf.filedownloader.FileDownloadConfiguration;
import org.wlf.filedownloader.FileDownloader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import okhttp3.OkHttpClient;

import static android.content.ContentValues.TAG;
/**
 * Created by Jane on 2017/6/23.
 */
public class HNAPPlication extends Application {
    private final static String CLIENT_PRI_KEY = "client.bks";
    private final static String TRUSTSTORE_PUB_KEY = "truststore.bks";
    private final static String SERVER_KEY = "server.cer";

    @Override
    public void onCreate() {
        super.onCreate();
        initOkhttp();
        // 在使用 SDK 各組間之前初始化 context 資訊,傳入 ApplicationContext
       
        checkAppReplacingState();

    }

    private void checkAppReplacingState() {
        if (getResources() == null) {
            Log.w(TAG, "app is replacing...kill");
            Process.killProcess(Process.myPid());
        }
    }

    private void initOkhttp() {
        //InputStream [] inputStreams=null;
        ClearableCookieJar cookieJar1 = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(getApplicationContext()));
//        inputStreams = new InputStream[4];
//        try {
////        inputStreams[0] = getClass().getResourceAsStream("/assets/newkey.cer");
//            inputStreams[0] = getAssets().open("newkey.cer");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        //讀取證書
        try {
            InputStream clientkey = getAssets().open(CLIENT_PRI_KEY);
            InputStream serverkey = getAssets().open(TRUSTSTORE_PUB_KEY);
            InputStream[] inputStreams = new InputStream[4];
//            inputStreams[0] = getClass().getResourceAsStream("/assets/" + SERVER_KEY);
                inputStreams[0] = getAssets().open(SERVER_KEY);


            HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(inputStreams, clientkey, "Eastcom_1");
//        CookieJarImpl cookieJar1 = new CookieJarImpl(new MemoryCookieStore());
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10000L, TimeUnit.MILLISECONDS)
                    .readTimeout(10000L, TimeUnit.MILLISECONDS)
                    .addInterceptor(new LoggerInterceptor("TAG"))
                    .cookieJar(cookieJar1)
                    .hostnameVerifier(new HostnameVerifier() {
                        @Override
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    })
                    .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                    .build();
            OkHttpUtils.initClient(okHttpClient);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }




}

HttpsUtil類
public class HttpsUtils
{
    public static class SSLParams
    {
        public SSLSocketFactory sSLSocketFactory;
        public X509TrustManager trustManager;
    }

    public static SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password)
    {
        SSLParams sslParams = new SSLParams();
        try
        {
            TrustManager[] trustManagers = prepareTrustManager(certificates);
            KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            X509TrustManager trustManager = null;
            if (trustManagers != null)
            {
                trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
            } else
            {
                trustManager = new UnSafeTrustManager();
            }
            sslContext.init(keyManagers, new TrustManager[]{trustManager},null);
            sslParams.sSLSocketFactory = sslContext.getSocketFactory();
            sslParams.trustManager = trustManager;
            return sslParams;
        } catch (NoSuchAlgorithmException e)
        {
            throw new AssertionError(e);
        } catch (KeyManagementException e)
        {
            throw new AssertionError(e);
        } catch (KeyStoreException e)
        {
            throw new AssertionError(e);
        }
    }

    private class UnSafeHostnameVerifier implements HostnameVerifier
    {
        @Override
        public boolean verify(String hostname, SSLSession session)
        {
            return true;
        }
    }

    private static class UnSafeTrustManager implements X509TrustManager
    {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException
        {
        }

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

        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return new java.security.cert.X509Certificate[]{};
        }
    }

    private static TrustManager[] prepareTrustManager(InputStream... certificates)
    {
        if (certificates == null || certificates.length <= 0) return null;
        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)

                {
                }
            }
            TrustManagerFactory trustManagerFactory = null;

            trustManagerFactory = TrustManagerFactory.
                    getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);

            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            return trustManagers;
        } catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        } catch (CertificateException e)
        {
            e.printStackTrace();
        } catch (KeyStoreException e)
        {
            e.printStackTrace();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;

    }

    private static KeyManager[] prepareKeyManager(InputStream bksFile, String password)
    {
        try
        {
            if (bksFile == null || password == null) return null;

            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            clientKeyStore.load(bksFile, password.toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(clientKeyStore, password.toCharArray());
            return keyManagerFactory.getKeyManagers();

        } catch (KeyStoreException e)
        {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e)
        {
            e.printStackTrace();
        } catch (CertificateException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers)
    {
        for (TrustManager trustManager : trustManagers)
        {
            if (trustManager instanceof X509TrustManager)
            {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }


    private static class MyTrustManager implements X509TrustManager
    {
        private X509TrustManager defaultTrustManager;
        private X509TrustManager localTrustManager;

        public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException
        {
            TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            var4.init((KeyStore) null);
            defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
            this.localTrustManager = localTrustManager;
        }


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

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
            try
            {
                defaultTrustManager.checkServerTrusted(chain, authType);
            } catch (CertificateException ce)
            {
                localTrustManager.checkServerTrusted(chain, authType);
            }
        }


        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[0];
        }
    }
}
Net請求配置
/**
 * Created by Jane on 2017/6/16.
 * 網路請求Api
 */
public class NetHttpApi {
    private Retrofit retrofit;
    //請求超時時間
    private static final int REQUEST_TIME = 10;
    private static NetHttpApi instance;
    private Context context;
    private OkHttpClient okHttpClient;
    private   InputStream[] inputStreams;
    private SSLSocketFactory sslSocketFactory;

    /**
     * @param urlType url訪問地址型別
     **/
    private NetHttpApi(int urlType, Context context) {
        this.context = context;
//        //日誌顯示級別
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();
        OkHttpClient client = aa();
        if (urlType == Contants.OLD_URL_TYPE) {
            retrofit = new Retrofit.Builder().client(client)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .baseUrl(Contants.APP_OLD_URL).build();
        } else if (urlType == Contants.NEW_URL_TYPE) {
            retrofit = new Retrofit.Builder().client(client)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .baseUrl(Contants.APP_URL).build();
        }
    }

    private OkHttpClient aa() {
        //日誌顯示級別
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
        //新建log攔截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.d("vvvvvvvvv", "OkHttp====Message==:" + message);
            }
        });
        loggingInterceptor.setLevel(level);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .sslSocketFactory(SSLHelper.getSSLCertifcation(context))
                .hostnameVerifier(new UnSafeHostnameVerifier())
                .addInterceptor(loggingInterceptor)
                .build();
        return okHttpClient;
    }
    /**
     * 建立單例模式,避免重複建立物件
     **/
    public static NetHttpApi getInstance(final int urlType, Context context) {
//        if (instance == null) {
//            synchronized (NetHttpApi.class) {
//                if (instance == null) {
//                    instance = new NetHttpApi(urlType,context);
//                }
//            }
//        }
        NetHttpApi netHttpApi = new NetHttpApi(urlType, context);
        return netHttpApi;
    }

    /**
     * 獲取一個service物件
     */
    public <T> T getService(Class<T> service) {
        return retrofit.create(service);
    }
}
SSLHelper
public class SSLHelper {
    private final static String CLIENT_PRI_KEY = "client.bks";
    private final static String TRUSTSTORE_PUB_KEY = "truststore.bks";
    private final static String CLIENT_BKS_PASSWORD = "Eastcom_1";
    private final static String TRUSTSTORE_BKS_PASSWORD = "Eastcom_1";
    private final static String KEYSTORE_TYPE = "BKS";
    private final static String PROTOCOL_TYPE = "TLS";
    private final static String CERTIFICATE_STANDARD = "X509";

    public static SSLSocketFactory getSSLCertifcation(Context context) {
        SSLSocketFactory sslSocketFactory = null;
        try {
            // 伺服器端需要驗證的客戶端證書,其實就是客戶端的keystore
            KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
            // 客戶端信任的伺服器端證書
            KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);
            //讀取證書
            InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);
            InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);

            //載入證書
            keyStore.load(ksIn, CLIENT_BKS_PASSWORD.toCharArray());
            trustStore.load(tsIn, TRUSTSTORE_BKS_PASSWORD.toCharArray());
            ksIn.close();
            tsIn.close();

            //初始化SSLContext
            SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_STANDARD);
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_STANDARD);
            trustManagerFactory.init(trustStore);
            keyManagerFactory.init(keyStore, CLIENT_BKS_PASSWORD.toCharArray());
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslSocketFactory;
    }
}
這是配置檔案,其他專案類 需要的話  私我

相關推薦

Https雙向認證Android客戶配置

Https雙向認證啊  做了兩遍,第一遍懵懂狀態處於 好不容易做好了,換伺服器,一下子懵了,使出渾身解數又找了一遍,這下終於好了  快哭啦,必須滴要記錄一下,以免以後遇到繼續懵,這裡用retrofit2+okhttp3為例子來簡單說明下 先來說說證書: 服務端提供的證書有四

JAX-RS RESTful webservice 服務客戶實現(基於HTTPS雙向認證)

在ApacheCXF的Sample裡以及網上很多有關RESTful HTTPS雙向認證的文章介紹僅僅是理論,沒有涉及實際環境的實現(客戶端和服務端都是localhost);這幾天使用Apache的CXF以及 Apache portable HttpClient實現跨IP的J

如何用Tomcat和Openssl構建HTTPS雙向認證環境(HTTPS客戶認證

本文將介紹如何利用Tomcat的HTTPS功能,和一個自己建立的CA,來構建WEB伺服器證書和個人數字證書,最終建成一個HTTPS雙向認證環境(可以用於測試目的)。本文構建HTTPS雙向認證的業務流程大致如下:  1. 建立WEB伺服器公鑰金鑰,並生成伺服器證書請求。  2.

OpenLDAP客戶配置,實現用戶認證(原創)

pen img sss fuse sys src file 由於 onf 1.工作過程 OpenLDAP服務分為客戶端和服務端兩個部分,服務端的配置過程這裏不再贅述。當服務端配置結束後,在服務端的ldap數據庫中,應存放著用戶的信息,客戶端通過安裝nss-p

XMPP學習——Android客戶與openfire伺服器單雙向TLS通訊

本文從TLS安全傳輸層協議的簡單流程、如何生成自簽名CA證書、自頒發伺服器&客戶端證書、配置openfire伺服器安全連線去描述如何建立一個使用TLS加密的XMPP聊天通道。 這裡的smack版本是V4.2.3,openfire伺服器版本也是V4.2.3

實現PHP伺服器+Android客戶(Retrofit+RxJava)第三天Retrofit的配置以及快取的實現

上一篇講了介面,這篇文章就要講客戶端網路請求部分的內容了,主要用到的就是Retrofit+RxJava,其實準確來說是Retrofit+RxJava+OkHttp, 最新的Retrofit是2.0.2版本,原始碼地址:retrofit 學習retrofit:

Tomcat伺服器配置https雙向認證

一,HTTPS原理 1,HTTP、HTTPS、SSL、TLS介紹與相互關係 (1) HTTP:平時瀏覽網頁時候使用的一種協議。HTTP協議傳輸的資料都是未加密的(明文),因此使用HTTP協議傳輸隱私資訊非常不安全。 (2)

Android 客戶 okhttp3 與伺服器之間的雙向驗證

本篇是Android 客戶端基於okhttp3的網路框架 和後臺伺服器之間的雙向驗證 分為三個階段 一:簡單的後臺伺服器搭建 二:客戶端接入okhttp3,並進行的網路請求 三:伺服器和客戶端的雙向驗證 第一步:   搭建簡單的伺服器 1:下載tomcat 2:配置

Apache下配置https雙向認證

1.Apache安裝並開啟ssl 略 2.建立證書 建立證書的步驟如下 2.1建立相關目錄 這裡apache目錄位於/data/webapps/apache 在apache目錄下建立ca目錄(方便管理,可自定義) mkdi

Android Https雙向認證 + GRPC

() pla pan sting ase 根證書 認證 hand cli keywords:android https 雙向認證android GRPC https 雙向認證 ManagedChannel channel = OkHttpChannelBuilder.

tomcat8配置https雙向認證

工具準備:keytool(JDK自帶證書生成工具),tomcat8 利用JDK中keyStore生成證書。 前言: 關於HTTPS介紹文章請看此博文,我也是看了他的博文才搞懂的,真心感謝。 博文地址:http://www.cnblogs.com/JeffreySun/ar

SSL--用Tomcat伺服器配置https雙向認證過程實戰

什麼是https? 百度百科足夠解釋它:http://baike.baidu.com/view/14121.htm 概述 A、 什麼是HTTPS在說HTTPS之前先說說什麼是HTTP,HTTP就是我們平時瀏覽網頁時候使用的一種協議。HTTP協議傳輸的資料都是未加密的,

android客戶直接呼叫芝麻信用的人臉認證

按理說,這些都應該是服務端完成的事情。可是由於種種原因,我放了一句狠話。。。 然後只能自己搞了。。。。 1、由於芝麻信用提供的SDK,在android端直接使用SSL證書驗證是不通過的。所以當時有點後悔說的狠話。 2、SDK用不了,沒辦法只能自己動手,

微軟Windows2008 AD+NPS配合無線控制器採用PEAP認證無線客戶配置(1)

思科無線控制器支援外接Radius介面,採用思科ACS 做為Radius來認證無線客戶端只是一種應用形式。很多客戶已經部署了微軟的Windows 2003/2008伺服器並希望通過微軟的架構實現Radius功能。這是可行的,例如Windows 2003 AD + IAS即

Android客戶與Java tomcat之間HTTPS通訊

文中涉及到https認證和post傳參。        不使用SSL(Secure Sockets Layer)/TLS的HTTP通訊就是不加密的通訊,所有資訊都已明文傳播,容易被竊取、篡改或冒充。SSL/TLS協議的基本思路是採用公鑰加密法:客戶端先向伺服器端索要公鑰,

用Tomcat伺服器配置https雙向認證過程實戰

什麼是https? 百度百科足夠解釋它:http://baike.baidu.com/view/14121.htm工具:keytool (Windows下路徑:%JAVA_HOME%/bin/keytool.exe)環境:Windows8.1企業版、Tomcat-7.0.2

HTTPS雙向認證+USB硬體加密鎖(加密狗)配置

環境:  Ubuntu14.04,apache2.4.7, openssl1.0.1f 安裝apache2 apt-get install apache2 -y 一般openssl預設已經安裝 開啟apache的ssl模組和ssl站點 a2enmod ssl a2ensi

NTP服務器搭建和客戶配置

position 服務器 relative middle border 1 搭建NTP服務器準備搭建環境主機IPOS備註NTP Server192.168.5.180CentOS 6NTP Client192.168.5.181CentOS 61.1 安裝NTP服務程序[[email

CnetOS 6.6 rsync 的服務客戶配置

rsync rsync 的服務端和客戶端配 linux centos 6.6 CentOS 6.6 rsync 的服務端和客戶端配置基本信息系統版本主機名IP地址角色CentOS 6.6backup10.0.0.10rsync服務端CentOS 6.6lamp0110.0.0.8rsync

WSUS服務器客戶配置說明

wsus服務器步驟1:win7執行【開始】I【運行】命令,在彈出的對話框中輸入gpedit.msc.單擊【確定】按鈕,打開【組策略編輯器】窗口,如圖1所示。  圖1【組策略編輯器】窗口 步驟2:依次展開【計算機配置】丨【管理模板】丨【Windows組件】丨【WindowsUpdate】結