區(qū)別
HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的,也就是明文的,因此使用HTTP協(xié)議傳輸隱私信息非常不安全,為了保證這些隱私數(shù)據(jù)能加密傳輸,于是網(wǎng)景公司設(shè)計(jì)了SSL(Secure Sockets Layer)協(xié)議用于對(duì)HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進(jìn)行加密,從而就誕生了HTTPS。
HTTPS和HTTP的區(qū)別主要如下:
1、https協(xié)議需要到ca申請(qǐng)證書(shū),一般免費(fèi)證書(shū)較少,因而需要一定費(fèi)用。
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡(jiǎn)單,是無(wú)狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。
HTTPS 工作原理、工作流程
1. 客戶(hù)端發(fā)起請(qǐng)求
2. 服務(wù)端配置公鑰私鑰。如果是使用購(gòu)買(mǎi)的證書(shū),把公鑰告訴客戶(hù)端。
3. 服務(wù)端把當(dāng)前此次請(qǐng)求的證書(shū)(公鑰)傳送過(guò)來(lái)

4. 客戶(hù)端進(jìn)行證書(shū)解析
客戶(hù)端會(huì)驗(yàn)證公鑰是否有效。如果沒(méi)有問(wèn)題,就回生成一個(gè)隨機(jī)值,并對(duì)其進(jìn)行加密,(這個(gè)隨機(jī)值其實(shí)就是對(duì)稱(chēng)加密的私鑰)
5. 將加密后的隨機(jī)值等加密信息傳給服務(wù)端
6.服務(wù)端解密信息
服務(wù)端用私鑰解密后,得到了客戶(hù)端傳過(guò)來(lái)的隨機(jī)值(私鑰),然后把內(nèi)容進(jìn)行對(duì)稱(chēng)加密。
7. 通信。因?yàn)榭蛻?hù)端跟服務(wù)端都有對(duì)稱(chēng)加密的秘鑰。所以ok了。
加密過(guò)程中的對(duì)稱(chēng)加密非對(duì)稱(chēng)加密
首先用的是非對(duì)稱(chēng)加密。把公鑰給客戶(hù)端,私鑰在服務(wù)端??蛻?hù)端用公鑰驗(yàn)證通過(guò)后,會(huì)生成私鑰進(jìn)行對(duì)稱(chēng)加密。然后傳給后臺(tái)。
為什么這么做呢。
- 對(duì)稱(chēng)加密加密與解密使用的是同樣的密鑰,所以速度快,但由于需要將密鑰在網(wǎng)絡(luò)傳輸,所以安全性不高。
- 非對(duì)稱(chēng)加密使用了一對(duì)密鑰,公鑰與私鑰,所以安全性高,但加密與解密速度慢。
- 所以第一次用公鑰私鑰驗(yàn)證。沒(méi)問(wèn)題之后,在用對(duì)稱(chēng)加密。這樣既安全又高效。
Android證書(shū)配置。結(jié)合流程看一下
/**
* 使用購(gòu)買(mǎi)的證書(shū)
*/
public static SSLSocketFactory getDefSSLSocketFactory() {
try {
//初始化SSLContext
SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
//驗(yàn)證服務(wù)端證書(shū)的公鑰
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (chain == null) {
throw new IllegalArgumentException("checkServerTrusted:x509Certificate array isnull");
}
if (!(chain.length > 0)) {
throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");
}
if (!(!TextUtils.isEmpty(authType) && authType.toUpperCase().contains("RSA"))) {
throw new CertificateException("checkServerTrusted: AuthType is not RSA");
}
// Hack ahead: BigInteger and toString(). We know a DER encoded Public Key begins
// with 0×30 (ASN.1 SEQUENCE and CONSTRUCTED), so there is no leading 0×00 to drop.
RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey();
/* signum:1表示是正數(shù);radix:16表示字節(jié)數(shù)組轉(zhuǎn)16進(jìn)制 */
String encoded = new BigInteger(1 /* positive */, pubkey.getEncoded()).toString(16);
final boolean expected = PUB_KEY.equalsIgnoreCase(encoded); //驗(yàn)證服務(wù)端證書(shū)的公鑰
if (!expected) {
throw new CertificateException("checkServerTrusted: got error public key:" + encoded);
}
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}};
//將隨機(jī)數(shù)等加密之后傳給服務(wù)端。
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
return sslContext.getSocketFactory();
} //省略各種異常處理,請(qǐng)自行添加
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
圖中的方法是驗(yàn)證服務(wù)端購(gòu)買(mǎi)的證書(shū)。如果是信任所有證書(shū)的。這三個(gè)重寫(xiě)的方法不需要做操作。直接用默認(rèn)即可。
參考感謝
詳細(xì)解析 HTTP 與 HTTPS 的區(qū)別
非對(duì)稱(chēng)加密和對(duì)稱(chēng)加密的區(qū)別
如有錯(cuò)誤。還望指正,非常感謝。