Https VS Http 效能比拼
今天在請求資料的資料的時候,伺服器使用的是https 請求,相對安全些,但是結果讓我請求圖片和資源的時候也使用https 請求,我之前寫的http 請求根本用不了!我就感到非常的不爽!最後聽公司的人說了下,最後他們決定 重要資訊使用hpps 訪問,但是對於資源什麼的就使用http 吧! 開始沒什麼認識,只感覺到使用https 請求資料的時候,要經過安全驗證,安全性很高!度娘了下!原來使用https 是要分場合的!不是什麼時候都可以用的!https 是為了安全性而設定的,要驗證很多的資訊!相對應 http 請求的速度肯定有點慢!最後看到下面的帖子,才明白,如果使用https 的話很麻煩的,無意給
微軟的很多網站都是通過https 加密過的!使用者的登陸驗證過程還可以理解,沒有想到所有的檔案資源居然也是通過https去訪問,這個其實就做的過於安全了。 一個幾十兆的流檔案,光服務端加密估計就要消耗很多cpu和能源了,不過微軟的伺服器夠power。 我們的客戶端瀏覽器 對這些資料要進行解密驗證,其實也耗費了很多的資源。那就稍微說下,在我們Android程式裡面訪問伺服器請求的時候儘量少使用 https 請求資料!否則非常的消耗
如果說我說的很浮虧,那麼我們就好好看看https 的效能吧:
1. HTTPS 一定要有明確的選擇理由.
a) HTTPS 實際上是SSL用於HTTP.
b) 主要解決了兩部分的問題.
i.
1. 信任主機的問題. 採用https 的server 必須從CA 申請一個用於證明伺服器用途型別的證書. 改證書只有用於對應的server 的時候,客戶度才信任次主機. 所以目前所有的銀行系統網站,關鍵部分應用都是https 的. 客戶通過信任該證書,從而信任了該主機. 其實這樣做效率很低,但是銀行更側重安全. 這一點對我們沒有任何意義,我們的server ,採用的證書不管自己issue 還是從公眾的地方issue, 客戶端都是自己人,所以我們也就肯定信任該server.
ii.
2. 通訊過程中的資料的洩密和被竄改. 這裡有兩個層次
1. 一般意義上的https, 就是 server 有一個證書.
a) 主要目的是保證server 就是他聲稱的server. 這個跟低一點一樣.
b) 服務端和客戶端中件的所有通訊,都是加密的.
i. 具體講,是客戶端產生一個對稱的金鑰,通過server 的證書來交換金鑰. 一般意義上的握手過程.
ii. 加下來所有的資訊往來就都是加密的. 第三方即使截獲,也沒有任何意義.因為他沒有金鑰. 當然竄改也就沒有什麼意義了.
2. 少許對客戶端有要求的情況下,會要求客戶端也必須有一個證書.
a) 這裡客戶端證書,其實就類似表示個人資訊的時候,除了使用者名稱/密碼, 還有一個CA 認證過的身份. 應為個人證書一般來說上別人無法模擬的,所有這樣能夠更深的確認自己的身份.
b) 目前少數個人銀行的專業版是這種做法,具體證書可能是拿U盤作為一個備份的載體.
(目前這種協議用於銀行等金融裡面比較多,例如炒股軟體,工商銀行什麼的!)
2. HTTPS 一定是expensive的.
a) 本來簡單的http協議,一個 get 一個response. 由於https 要還金鑰和確認加密演算法的需要.單握手就需要6/7 個往返.
i. 任何應用中,過多的round trip 肯定影響效能.
b) 接下來才是具體的http協議,每一次響應或者請求, 都要求客戶端和服務端對會話的內容做加密/解密.
i. 儘管對稱加密/解密效率比較高,可是仍然要消耗過多的CPU,為此有專門的SSL 晶片. 如果CPU 信能比較低的話,肯定會降低效能,從而不能serve 更多的請求.
ii. 加密後資料量的影響.
1. 這個我用128bit 的RC2 測試了一下,加密後數量跟加密前基本相同.
3. HTTP VS HTTPS 的效能
a) 這個由於很多人測試的背景不一樣,由於時間太緊,我沒有寫出了一個類似 ACT 一樣測試web https 的壓力工具. 看了一下別人的觀點.
b) 有些人說https 的效能是 http 的 40 % , 有些人說可能80%.
c) 我的觀點.
i. https 的關鍵效能影響是 CPU 和往返. 如果CPU 很強的話, 效能可能就是有人講的80%. 如果cpu 是瓶頸的話, 有人講原來可以server 330-500個請求每秒,現在只有30-50%
ii. 不需要用https 的地方,就儘量不要用.
這就是區別!
因此在使用https 請求資料的時候要注意看看你的專案裡面是否真的需要! 我在此給你一段 使用Android訪問https 的程式碼:
private X509TrustManager xtm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
// System.out.println("cert: " + chain[0].toString() + ", authType: "
// + authType);
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
private HostnameVerifier hnv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
//讀取證書
return true;
}
};
private HttpsUtils() {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
X509TrustManager[] xtmArray = new X509TrustManager[] { xtm };
sslContext.init(null, xtmArray, new java.security.SecureRandom());
} catch (GeneralSecurityException gse) {
}
if (sslContext != null) {
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
.getSocketFactory());
}
HttpsURLConnection.setDefaultHostnameVerifier(hnv);
}
private static HttpsUtils instance = null;
public static HttpsUtils getInstance(){
if (instance == null) {
instance = new HttpsUtils();
}
return instance;
}