標籤:rtc puts jdk false 資料安全 $$ code 要求 ati
HTTPS ,該來的總要來的。
最近領導對移動端開發提出了很多最佳化的要求啊!其中一點就是資料安全性,之前安卓後端介面一直是用的HTTP,那麼我想了想,HTTPS應該是入門級的了,趕緊找資料整理了下!
對於向權威機構申請過認證的網路地址,用OkHttp或者HttpsURLConnection都可以直接存取,不需要做額外的事情。但是申請認證要$$的,所以開發的時候我們介面經常是使用自我簽署憑證,或者即使上線了也還是用自簽名的,因為安卓用到的基本都是資料介面,又不會用瀏覽器訪問,不想付錢不行咩!
訪問自簽名網址
使用keytool產生認證
keytool是JDK提供的管理加密金鑰、X.509憑證鏈結和可信認證密鑰庫的簡便工具。安卓開發必定安裝了JDK並且一般都會配置好環境變數,所以你可以直接在終端或DOC視窗輸入keytool命令來查看協助。
1.產生金鑰組
1
keytool -genkey -alias server -keyalg RSA -keystore server.jks
-alias後面跟的是唯一別名,-keystore後面填儲存秘鑰對的檔案路徑
還可以添加一個-validity 天數聲明有效期間
需要注意的地方:執行命令之後第一個問題讓你輸入名字的地方最好設定成網域名稱,比如這樣baidu.com或者這樣localhost,反正匹配你要調式的網域名稱就對了,當然,如果你在安卓上調試,那麼本地地址可能用不了。
2.匯出認證
上面產生了服務端使用的金鑰組,現在可以通過它產生認證給用戶端使用
1
keytool -export -alias server -storepass 123456 -keystore server.jks -file server.cer
-storepass後面跟的是你剛才設定的密碼,不加這個也沒關係,它會主動問你!;-file設定了儲存認證的路徑
服務端配置
這裡我使用tomcat8進行測試,它的配置很簡單,修改tomcat目錄下的conf/server.xml檔案,添加如下內容,這裡設定了連接埠號碼為8443
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="密鑰庫檔案路徑,也就是.jks檔案"
keystorePass="密碼" />
安卓端配置
載入認證
把之前產生的認證(.cer)放到安卓項目的assets或者raw目錄下,讀取檔案流用以下方法擷取SSLSocketFactory 。
public static SSLSocketFactory getSslSocketFactory(InputStream certificates)
{
SSLContext sslContext = null;
try
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Certificate ca; try { ca = certificateFactory.generateCertificate(certificates); } finally { certificates.close(); } // Create a KeyStore containing our trusted CAs String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); // Create a TrustManager that trusts the CAs in our KeyStore String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); // Create an SSLContext that uses our TrustManager sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); } catch (Exception e) { e.printStackTrace(); } return sslContext != null? sslContext.getSocketFactory():null;}
OkHttp
在OkHttp中使用很簡單,擷取SSLSocketFactory之後通過OkHttp的構建方法傳入就行了。
使用的OkHttp版本是3.2.0。
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory)
.build();
設定完之後你就可以訪問該認證對應的網域名稱地址了,不需要別的附加操作了。
HttpsURLConnection
OkHttp的API與安卓中預設提供的URLConnection是很接近的,所以配置也是如出一轍。
URL url = new URL("https://....");
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setSSLSocketFactory(sslSocketFactory);
雙向驗證
雙向認證需要兩個密鑰實體,一個放服務端一個放用戶端。
前面我們已經實現單向的認證,現在只需要給用戶端產生一個密鑰庫,並且讓服務端信任用戶端就可以了。
產生用戶端密鑰
keytool -genkey -alias android -keyalg RSA -keystore android.jks
匯出用戶端認證(字串形式)
keytool -keystore android.jks -alias android -exportcert -rfc > android.pem
將匯出的認證添加信任到服務端的密鑰庫
keytool -importcert -trustcacerts -alias android -keystore server.jks -file android.pem
服務端配置
修改tomcat目錄下的conf/server.xml檔案
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
sslProtocol="TLS"
keystoreFile="密鑰庫檔案路徑,也就是.jks檔案"
keystorePass="密碼"
//修改兩條內容,其它和之前單向認證一樣就行
clientAuth="true"
truststoreFile="和keystoreFile填一樣" />
Android 偶遇HTTPS