您好,登錄后才能下訂單哦!
為了確保數據傳輸的安全,現在越來越多的應用使用Https的方式來進行數據傳輸,使用https有很多有點,比如:
但是即使使用HTTPS有很多有點,但是購買一個認證的HTTPS證書卻價格不菲,增加了初創企業和小團隊的開發成本。而且如上面所說,使用HTTPS并非絕對的安全,傳輸的數據并非沒有辦法獲取到,我的之前一篇博客所使用的方法已成功截取HTTPS的數據傳輸。有興趣的可以參考:使用Charles對Android App的https請求進行抓包。
為了節約成本,我們可以選擇使用自簽名的HTTPS。
這種方式我們可以自己生成證書,不需要購買證書,但是使用這種方式的域名如果在瀏覽器中訪問的話,會有一個不安全的標識。但是如果用在客戶端上,就不會有這個問題,現在一些應用商店也要求APP上架時需要使用HTTPS的網絡請求(比如AppStore),使用這種自簽名的HTTPS同樣也能過審。
本文我們介紹在Android上使用網絡請求框架Retrofit 2來請求自簽名的API,關于如何生成HTTPS證書,我們將在另一篇博客中進行說明,敬請期待。或者您可以自行查找相關資料。
比如我們生成的SLL證書文件為"api_ssl_debug.cer",我們將其放到assets目錄下。這樣在配置Retrofit的時候就可以讀取該證書并用于API請求中。
本節我們介紹SSL證書在Retrofit中的配置,首先我們要定義兩個方法用來讀取證書,然后講該證書用于Retrofit中。
private static KeyStore getKeyStore(String fileName) {
KeyStore keyStore = null;
try {
AssetManager assetManager = Utils.getApp().getAssets();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = assetManager.open(fileName);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.d("SslUtils", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
} catch (Exception e) {
Log.e("SslUtils", "Error during getting keystore", e);
}
return keyStore;
}
public static SSLContext getSslContextForCertificateFile(String fileName) {
try {
KeyStore keyStore = SslUtils.getKeyStore(fileName);
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext;
} catch (Exception e) {
String msg = "Error during creating SslContext for certificate from assets";
Log.e("SslUtils", msg, e);
throw new RuntimeException(msg);
}
}
SSLContext sslContext = SslUtils.getSslContextForCertificateFile("api_ssl_debug.cer");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
OkHttpClient.Builder builder = new OkHttpClient.Builder()
...
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.hostnameVerifier((hostname, session) -> true)
...
mRetrofit = new Retrofit.Builder()
...
build();
以上的省略號為Retrofit的其它配置,可以根據工程需要進行配置。
至此,使用Retrofit就可以進行自簽名的HTTPS的網絡請求了,當然,服務器端的API配置也需要進行HTTPS的配置,我將在服務端相關的博客進行介紹,還有一點,如果請求的域名指定了端口,要將端口設置為443。如果沒有指定端口,請求時也會自動走443端口。
本文原始地址,如有更多疑問,請參考我的其它Android相關博客:我的博客地址
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。