Android數據傳輸加密

對稱加密

  • 採用單密鑰加密,加解密密鑰同一份
  • 代表算法:DES、3DES、AES、RC2、RC4
  • 優點:加解密效率高,算法簡單,適合加密大量數據。
  • 缺點:密鑰維護複雜,泄漏後就沒有安全性可言

非對稱加密

  • 非對稱加密公私鑰,一個密鑰用於加密,另外一個解密
  • 代表算法:RSA、ECC
  • 優點:安全性高,由公鑰無法推導私鑰,適應網絡傳輸場景
  • 缺點:加密效率偏低

HTTP/HTTPS

HTTP/HTTPS 請求與防抓包

APP網絡應用場景

  1. 使用http,不做任何加密相當於裸奔,初級工程師都可以輕易窺探你全部的業務數據。
  2. 使用http,但所有的流量都通過預埋在客戶端的key進行AES加密,流量基本安全,不過一旦客戶端代碼被反編譯竊取key又會會到裸奔狀態
  3. 使用http,但AES使用的key通過客戶端以GUID的方式臨時生成,爲來保證key能安全送達服務器,勢必要使用服務器的公鑰進行加密,所以要預埋服務器證書,又涉及到證書過期更新機制,而且無法動態協商使用的對稱加密算法,安全性還是又暇疵。

加密傳輸安全建議

  • 儘量使用https
  • 不要明文傳輸密碼
  • 請求帶上數據簽名防篡改
  • http請求使用臨時密鑰
  • AES使用CBC模式
  • post並不比get安全,都要加密和簽名處理

https證書校驗

  • CA(Certificate Authority).CA用自己的私鑰簽發數字證書,數字證書中包含A的公鑰。然後B可以用CA的根證書中的公鑰來解密CA簽發的證書,從而拿到合法的公鑰

  • 中間CA:大多數CA不直接簽署服務器證書,而是簽署中間CA,然後用中間CA來簽署服務器證書。這樣根證書可以離線存儲來確保安全,及時中間證書出來問題,可以用根證書重新簽署中間證書。

  • 證書校驗:HTTPS握手開始後,服務器會把整個證書鏈發送到客戶端,給客戶端做校驗。校驗的過程是要找到這樣一條證書鏈,鏈中每個相鄰節點,上級的公鑰可以校驗通過下級的證書,鏈的根節點是設備信任的錨點。

https配置

服務端

  • 服務端生成公私鑰對
  • 給Tomcat服務器配置https
  • 導出證書

客戶端

  • 將證書集成到APK文件中
  • 發送網絡請求,獲取證書,讀取https網站的數據

https API

HttpsURLConnection

URL url = new URL("https://google.com");
 HttpsURLConnection urlConnection = url.openConnection(); 
 InputStream in = urlConnection.getInputStream();

SSLSocketFactory

private synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
		try {
			SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, null, null);
			return defaultSslSocketFactory = sslContext.getSocketFactory(); 
		} catch (GeneralSecurityException e) {
			throw new AssertionError();
		 }
}

TrustManager

public interface X509TrustManager extends TrustManager {
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException;
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException;
		public X509Certificate[] getAcceptedIssuers(); 
}

https驗證證書問題

SSLHandshakeException

  • 頒發服務器證書的CA未知
  • 服務器證書不是CA簽名的,而是自簽名的
  • 服務器配置缺少中間CA

自定義信任策略

// 取到證書的輸入流
InputStream stream = getAssets().open(“server.crt");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(null);
Certificate certificate =
         CertificateFactory.getInstance("X.509").generateCertificate(stream);
// 創建Keystore包含我們的證書 keystore.setCertificateEntry(“ca", certificate);
// 創建TrustManager,僅信任keyStore中的證書
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore);
//用TrustManager初始化一個SSLContext
SSLContext context = SSLContext.getInstance("TLS");
 context.init(null, tmf.getTrustManagers(), null);
 URL url = new URL(path);
 HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(context.getSocketFactory());
指示HttpsUrlConnection信任指定CA
InputStream in = urlConnection.getInputStream();

Android安全開發之安全使用HTTPS

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章