1. 前言java
HTTPS愈來愈成爲主流,谷歌從 2017 年起,Chrome 瀏覽器將也會把採用 HTTP 協議的網站標記爲「不安全」網站;蘋果從 2017 年 iOS App 將強制使用 HTTPS;在國內熱火朝天的小程序也要求必須使用 HTTPS 請求。那麼爲何要使用HTTPS呢?首先說爲何使用https,簡單點說就是爲了防止數據傳輸過程當中信息被竊取或偷換,防止中間人攻擊。小程序
2. 準備BKS證書,將證書放到項目raw目錄下瀏覽器
準備.cer文件安全
能夠跟後臺開發人員直接拿,也能夠直接在網站上下載socket
在網站上下載:maven
點擊地址欄前面的小鎖頭,而後點擊證書信息ide
將.cer轉換爲.bks網站
首先要下載bouncycastle的JARui
http://repo2.maven.org/maven2/org/bouncycastle/bcprov-jdk16/1.46/bcprov-jdk16-1.46.jarspa
解壓後在當前文件夾執行如下命令
keytool -importcert -v -trustcacerts -file 「server.cert」 -alias server_alias -keystore 「server.bks」 -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath 「bcprov-jdk16-146.jar」 -storetype BKS -storepass password
黑體字部分是你要修改的,其中 「server.cert」是原cer證書的名字,「server_alias」是別名,「server.bks」是轉換後bks證書的名字,「password」是你證書的密碼,下邊會用到的。
成功後將.bks證書文件放到項目的raw目錄下。
3. 獲取SSLSocketFactory
這裏是HTTPS證書認證的關鍵代碼,注意password和設置keystore的bks類型必定不要搞錯。
/** * 獲取bks文件的sslsocketfactory * @param context * @return */ public static SSLSocketFactory getSSLSocketFactory(Context context) { final String CLIENT_TRUST_PASSWORD = "123456";//信任證書密碼,該證書默認密碼是123456 final String CLIENT_AGREEMENT = "TLS";//使用協議 final String CLIENT_TRUST_KEYSTORE = "BKS"; SSLContext sslContext = null; try { //取得SSL的SSLContext實例 sslContext = SSLContext.getInstance(CLIENT_AGREEMENT); //取得TrustManagerFactory的X509密鑰管理器實例 TrustManagerFactory trustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); //取得BKS密庫實例 KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE); InputStream is = context.getResources().openRawResource(R.raw.traint); try { tks.load(is, CLIENT_TRUST_PASSWORD.toCharArray()); } finally { is.close(); } //初始化密鑰管理器 trustManager.init(tks); //初始化SSLContext sslContext.init(null, trustManager.getTrustManagers(), null); } catch (Exception e) { e.printStackTrace(); Log.e("SslContextFactory", e.getMessage()); } return sslContext.getSocketFactory(); }
4.配置retrofit
String baseUrl = "https://skyish-test.yunext.com"; int[] certificates = {R.raw.traint}; String[] hostUrls = {baseUrl}; OkHttpClient client = new okhttp3.OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .sslSocketFactory(HTTPSUtils.getSSLSocketFactory(context)) //.hostnameVerifier(HTTPSUtils.getHostNameVerifier(hostUrls)) .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .build(); Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(client) .build();
配置好這個就能夠使用HTTPS鏈接了。
5.常見錯誤
SSLContext is not initialized.
緣由:
1. 證書和證書密碼不匹配。
2. 使用了錯誤的證書。證書類型不對,記得要用bks格式的證書文件。