Https原理及流程
原文地址
我們知道,HTTP請求都是明文傳輸的,所謂的明文指的是沒有經過加密的信息,如果HTTP請求被黑客攔截,并且里面含有銀行卡密碼等敏感數據的話,會非常危險。為了解決這個問題,Netscape 公司制定了HTTPS協議,HTTPS可以將數據加密傳輸,也就是傳輸的是密文,即便黑客在傳輸過程中攔截到數據也無法破譯,這就保證了網絡通信的安全。
密碼學基礎
在正式講解HTTPS協議之前,我們首先要知道一些密碼學的知識。
明文: 明文指的是未被加密過的原始數據。
密文:明文被某種加密算法加密之后,會變成密文,從而確保原始數據的安全。密文也可以被解密,得到原始的明文。
密鑰:密鑰是一種參數,它是在明文轉換為密文或將密文轉換為明文的算法中輸入的參數。密鑰分為對稱密鑰與非對稱密鑰,分別應用在對稱加密和非對稱加密上。
對稱加密:對稱加密又叫做私鑰加密,即信息的發送方和接收方使用同一個密鑰去加密和解密數據。對稱加密的特點是算法公開、加密和解密速度快,適合于對大數據量進行加密,常見的對稱加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。
其加密過程如下:明文 + 加密算法 + 私鑰 => 密文
解密過程如下:密文 + 解密算法 + 私鑰 => 明文
對稱加密中用到的密鑰叫做私鑰,私鑰表示個人私有的密鑰,即該密鑰不能被泄露。
其加密過程中的私鑰與解密過程中用到的私鑰是同一個密鑰,這也是稱加密之所以稱之為“對稱”的原因。由于對稱加密的算法是公開的,所以一旦私鑰被泄露,那么密文就很容易被破解,所以對稱加密的缺點是密鑰安全管理困難。
非對稱加密:非對稱加密也叫做公鑰加密。非對稱加密與對稱加密相比,其安全性更好。對稱加密的通信雙方使用相同的密鑰,如果一方的密鑰遭泄露,那么整個通信就會被破解。而非對稱加密使用一對密鑰,即公鑰和私鑰,且二者成對出現。私鑰被自己保存,不能對外泄露。公鑰指的是公共的密鑰,任何人都可以獲得該密鑰。用公鑰或私鑰中的任何一個進行加密,用另一個進行解密。
被公鑰加密過的密文只能被私鑰解密,過程如下:
明文 + 加密算法 + 公鑰 => 密文, 密文 + 解密算法 + 私鑰 => 明文
被私鑰加密過的密文只能被公鑰解密,過程如下:
明文 + 加密算法 + 私鑰 => 密文, 密文 + 解密算法 + 公鑰 => 明文
由于加密和解密使用了兩個不同的密鑰,這就是非對稱加密“非對稱”的原因。
非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少量數據進行加密。
在非對稱加密中使用的主要算法有:RSA、Elgamal、Rabin、D-H、ECC(橢圓曲線加密算法)等。
HTTPS通信過程
HTTPS協議 = HTTP協議 + SSL/TLS協議,在HTTPS數據傳輸的過程中,需要用SSL/TLS對數據進行加密和解密,需要用HTTP對加密后的數據進行傳輸,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。
SSL的全稱是Secure Sockets Layer,即安全套接層協議,是為網絡通信提供安全及數據完整性的一種安全協議。SSL協議在1994年被Netscape發明,后來各個瀏覽器均支持SSL,其最新的版本是3.0
TLS的全稱是Transport Layer Security,即安全傳輸層協議,最新版本的TLS(Transport Layer Security,傳輸層安全協議)是IETF(Internet Engineering Task Force,Internet工程任務組)制定的一種新的協議,它建立在SSL 3.0協議規范之上,是SSL 3.0的后續版本。在TLS與SSL3.0之間存在著顯著的差別,主要是它們所支持的加密算法不同,所以TLS與SSL3.0不能互操作。雖然TLS與SSL3.0在加密算法上不同,但是在我們理解HTTPS的過程中,我們可以把SSL和TLS看做是同一個協議。
HTTPS為了兼顧安全與效率,同時使用了對稱加密和非對稱加密。數據是被對稱加密傳輸的,對稱加密過程需要客戶端的一個密鑰,為了確保能把該密鑰安全傳輸到服務器端,采用非對稱加密對該密鑰進行加密傳輸,總的來說,對數據進行對稱加密,對稱加密所要使用的密鑰通過非對稱加密傳輸。
以下圖片來自于limboy的博客
image.png
HTTPS在傳輸的過程中會涉及到三個密鑰:
服務器端的公鑰和私鑰,用來進行非對稱加密
客戶端生成的隨機密鑰,用來進行對稱加密
一個HTTPS請求實際上包含了兩次HTTP傳輸,可以細分為8步。
1.客戶端向服務器發起HTTPS請求,連接到服務器的443端口
2.服務器端有一個密鑰對,即公鑰和私鑰,是用來進行非對稱加密使用的,服務器端保存著私鑰,不能將其泄露,公鑰可以發送給任何人。
3.服務器將自己的公鑰發送給客戶端。
4.客戶端收到服務器端的公鑰之后,會對公鑰進行檢查,驗證其合法性,如果發現發現公鑰有問題,那么HTTPS傳輸就無法繼續。嚴格的說,這里應該是驗證服務器發送的數字證書的合法性,關于客戶端如何驗證數字證書的合法性,下文會進行說明。如果公鑰合格,那么客戶端會生成一個隨機值,這個隨機值就是用于進行對稱加密的密鑰,我們將該密鑰稱之為client key,即客戶端密鑰,這樣在概念上和服務器端的密鑰容易進行區分。然后用服務器的公鑰對客戶端密鑰進行非對稱加密,這樣客戶端密鑰就變成密文了,至此,HTTPS中的第一次HTTP請求結束。
5.客戶端會發起HTTPS中的第二個HTTP請求,將加密之后的客戶端密鑰發送給服務器。
6.服務器接收到客戶端發來的密文之后,會用自己的私鑰對其進行非對稱解密,解密之后的明文就是客戶端密鑰,然后用客戶端密鑰對數據進行對稱加密,這樣數據就變成了密文。
7.然后服務器將加密后的密文發送給客戶端。
8.客戶端收到服務器發送來的密文,用客戶端密鑰對其進行對稱解密,得到服務器發送的數據。這樣HTTPS中的第二個HTTP請求結束,整個HTTPS傳輸完成。
數字證書
通過觀察HTTPS的傳輸過程,我們知道,當服務器接收到客戶端發來的請求時,會向客戶端發送服務器自己的公鑰,但是黑客有可能中途篡改公鑰,將其改成黑客自己的,所以有個問題,客戶端怎么信賴這個公鑰是自己想要訪問的服務器的公鑰而不是黑客的呢? 這時候就需要用到數字證書。
在講數字證書之前,先說一個小例子。假設一個鎮里面有兩個人A和B,A是個富豪,B想向A借錢,但是A和B不熟,怕B借了錢之后不還。這時候B找到了鎮長,鎮長給B作擔保,告訴A說:“B人品不錯,不會欠錢不還的,你就放心借給他吧。” A聽了這話后,心里想:“鎮長是全鎮最德高望重的了,他說B沒問題的話那就沒事了,我就放心了”。 于是A相信B的為人,把錢借給了B。
與此相似的,要想讓客戶端信賴公鑰,公鑰也要找一個擔保人,而且這個擔保人的身份必須德高望重,否則沒有說服力。這個擔保人的就是證書認證中心(Certificate Authority),簡稱CA。 也就是說CA是專門對公鑰進行認證,進行擔保的,也就是專門給公鑰做擔保的擔保公司。 全球知名的CA也就100多個,這些CA都是全球都認可的,比如VeriSign、GlobalSign等,國內知名的CA有WoSign。
那CA怎么對公鑰做擔保認證呢?CA本身也有一對公鑰和私鑰,CA會用CA自己的私鑰對要進行認證的公鑰進行非對稱加密,此處待認證的公鑰就相當于是明文,加密完之后,得到的密文再加上證書的過期時間、頒發給、頒發者等信息,就組成了數字證書。
不論什么平臺,設備的操作系統中都會內置100多個全球公認的CA,說具體點就是設備中存儲了這些知名CA的公鑰。當客戶端接收到服務器的數字證書的時候,會進行如下驗證:
首先客戶端會用設備中內置的CA的公鑰嘗試解密數字證書,如果所有內置的CA的公鑰都無法解密該數字證書,說明該數字證書不是由一個全球知名的CA簽發的,這樣客戶端就無法信任該服務器的數字證書。
如果有一個CA的公鑰能夠成功解密該數字證書,說明該數字證書就是由該CA的私鑰簽發的,因為被私鑰加密的密文只能被與其成對的公鑰解密。
除此之外,還需要檢查客戶端當前訪問的服務器的域名是與數字證書中提供的“頒發給”這一項吻合,還要檢查數字證書是否過期等。
通過瀏覽器直接獲取服務器的公鑰很容易,各個瀏覽器操作大同小異。百度現在已經實現了全站點HTTPS,我們就以百度為例如何從Chrome中獲取其公鑰。
用Chrome打開百度首頁,在https左側我們會發現有一個綠色的鎖頭。?
點擊該鎖頭,出現一個彈出面板,點擊面板中的“詳細信息”幾個字。?
這是會打開Chrome的Developer Tool,并自動切換到Security這個頁面。?
點擊“View ceertificate”按鈕就可以查看該網站的證書了,如下所示:?
在“常規”這個面板中,我們從中可以查看該證書是又Symantec頒發給baidu.com這個網站的,有效期是從2015年9月17到2016年9月1日。
切換到“詳細信息”面板,可以查看證書的一些詳細信息,比如證書所使用的數字簽名的算法,如下圖所示:?
上面有個“復制到文件”的按鈕,點擊該按鈕就可以將百度的數字證書導出成文件,從而我們就可以保存到自己的機器上,界面如下所示:
我們將其導出成X.509格式的證書,以.cer作為文件擴展名,最后保存到本地機器如下所示:?
切換到“證書路徑”面板,可以查看證書的證書鏈。?
這里先解釋一下什么是證書鏈。我們之前提到,VeriSign是一個全球知名的CA,但是一般情況下,CA不會用自己的私鑰去直接簽名某網站的數字證書,一般CA會首先簽發一種證書,然后用這種證書再去簽發百度等的數字證書。在此例中,VeriSign簽發了Symantec證書,然后Symantec又簽發了baiduc.om,VeriSign位于最頂端,類似于根結點,因此叫做根CA,Symatec位于中間,叫做中間CA,當然,有可能有多個中間CA,這樣從根CA到中間CA,再到最終的網站的證書,這樣自上而下形成了一條證書鏈。如果想要查看證書鏈中的某個證書,只需要選中它,比如選中了Symantec,然后點擊下面的“查看證書”按鈕就會彈出另一個對話框,在其中可以查看Symantec的數字證書,當然也可以將其導出成證書文件保存在硬盤上。
Android中訪問HTTPS
在Android中我們也會經常發送HTTPS請求,這時需要使用HttpsURLConnection這個類,HttpsURLConnection是繼承自HttpURLConnection的,其用法跟HttpURLConnection是一樣的,比如我們想用HTTPS訪問百度的首頁,代碼如下所示:
URL url = new URL("https://www.baidu.com");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
InputStream is = conn.getInputStream();
...
1
2
3
4
我們通過得到的InputStream就可以解析服務器的返回結果了。
如果對應服務器的數字證書存在問題,那么客戶端就無法信任該證書,從而無法建立HTTPS鏈接,我們以國內的12306.cn網站為例進行說明。
12306.cn的用戶登錄是需要HTTPS的訪問的,如果瀏覽器第一次打開頁面https://kyfw.12306.cn/otn/regist/init,那么瀏覽器要么顯示證書警告信息,要么索性直接不顯示頁面,因為12306.cn的數字證書存在問題。
其證書鏈如下所示:?
大家可以看到,該12306.cn的證書是由SRCA這個機構簽發的,也就是說SRCA是證書鏈上的根CA。
但是SRCA是啥呢?沒聽過啊!
我們選中SRCA后,點擊“查看證書”按鈕,SRCA的證書如下所示:?
也就是說SRCA的全稱是Sinorail Certification Authority, 在百度里面搜索該名稱,可以查到一個叫做中鐵信息工程集團的網站,http://www.sinorail.com/ProductInfos.aspx?id=185,里面有這么一段描述:?
也就是說SRCA是鐵道部給旗下的網站等做簽名的一個所謂CA,但是它不具備公信力,因為它不是一個全球知名的CA,所以客戶端根本不認可它。
我們在Android中直接訪問https://kyfw.12306.cn/otn/regist/init時,會得到如下異常:?
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
這是因為Android的客戶端內置的可信任CA列表中沒有包含所謂的SRCA,這樣就出現了12306.cn的證書不被客戶端信任的異常。
為了解決客戶端不信任服務器數字證書的問題,網絡上大部分的解決方案都是讓客戶端不對證書做任何檢查,這是一種有很大安全漏洞的辦法,如下所示:?
首先定義一個自己的SSLTrustAllManager,其繼承自X509TrustManager,具體來說,用SSLTrustAllManager創建一個SSLContext,然后用SSLContext生成一個SSLSocketFactory,然后通過調用HttpURLConnectoin的setSSLSocketFactory方法將其給某個具體的連接對象使用。由于SSLTrustAllManager沒有對其中的三個核心方法進行具體實現,也就是不對證書做任何審查。這樣無論服務器的證書如何,都能建立HTTPS連接,因為客戶端直接忽略了驗證服務器證書這一步。
這樣雖然能建立HTTPS連接,但是存在很大的安全漏洞。因為黑客有可能攔截到我們的HTTPS請求,然后黑客用自己的假證書冒充12306.cn的數字證書,由于客戶端不對證書做驗證,這樣客戶端就會和黑客的服務器建立連接,這樣會導致客戶端把自己的12306的賬號和密碼發送給了黑客,所以客戶端不對證書做任何驗證的做法有很大的安全漏洞。
解決此問題的辦法是讓Android客戶端信任12306的證書,而不是不對證書做任何檢查。
我們通過上面提到的方法得到12306的證書12306.cer,將其放到assets目錄下,也就是將12306.cer打包到我們的App中,然后用如下代碼訪問12306的HTTPS站點。
class DownloadThread extends Thread{
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? HttpsURLConnection conn = null;
? ? ? ? ? ? InputStream is = null;
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? URL url = new URL("https://kyfw.12306.cn/otn/regist/init");
? ? ? ? ? ? ? ? conn = (HttpsURLConnection)url.openConnection();
? ? ? ? ? ? ? ? //創建X.509格式的CertificateFactory
? ? ? ? ? ? ? ? CertificateFactory cf = CertificateFactory.getInstance("X.509");
? ? ? ? ? ? ? ? //從asserts中獲取證書的流
? ? ? ? ? ? ? ? InputStream cerInputStream = getAssets().open("12306.cer");//SRCA.cer
? ? ? ? ? ? ? ? //ca是java.security.cert.Certificate,不是java.security.Certificate,
? ? ? ? ? ? ? ? //也不是javax.security.cert.Certificate
? ? ? ? ? ? ? ? Certificate ca;
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? //證書工廠根據證書文件的流生成證書Certificate
? ? ? ? ? ? ? ? ? ? ca = cf.generateCertificate(cerInputStream);
? ? ? ? ? ? ? ? ? ? System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
? ? ? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? ? ? cerInputStream.close();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 創建一個默認類型的KeyStore,存儲我們信任的證書
? ? ? ? ? ? ? ? String keyStoreType = KeyStore.getDefaultType();
? ? ? ? ? ? ? ? KeyStore keyStore = KeyStore.getInstance(keyStoreType);
? ? ? ? ? ? ? ? keyStore.load(null, null);
? ? ? ? ? ? ? ? //將證書ca作為信任的證書放入到keyStore中
? ? ? ? ? ? ? ? keyStore.setCertificateEntry("ca", ca);
? ? ? ? ? ? ? ? //TrustManagerFactory是用于生成TrustManager的,我們創建一個默認類型的TrustManagerFactory
? ? ? ? ? ? ? ? String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
? ? ? ? ? ? ? ? TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
? ? ? ? ? ? ? ? //用我們之前的keyStore實例初始化TrustManagerFactory,這樣tmf就會信任keyStore中的證書
? ? ? ? ? ? ? ? tmf.init(keyStore);
? ? ? ? ? ? ? ? //通過tmf獲取TrustManager數組,TrustManager也會信任keyStore中的證書
? ? ? ? ? ? ? ? TrustManager[] trustManagers = tmf.getTrustManagers();
? ? ? ? ? ? ? ? //創建TLS類型的SSLContext對象, that uses our TrustManager
? ? ? ? ? ? ? ? SSLContext sslContext = SSLContext.getInstance("TLS");
? ? ? ? ? ? ? ? //用上面得到的trustManagers初始化SSLContext,這樣sslContext就會信任keyStore中的證書
? ? ? ? ? ? ? ? sslContext.init(null, trustManagers, null);
? ? ? ? ? ? ? ? //通過sslContext獲取SSLSocketFactory對象
? ? ? ? ? ? ? ? SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
? ? ? ? ? ? ? ? //將sslSocketFactory通過setSSLSocketFactory方法作用于HttpsURLConnection對象
? ? ? ? ? ? ? ? //這樣conn對象就會信任我們之前得到的證書對象
? ? ? ? ? ? ? ? conn.setSSLSocketFactory(sslSocketFactory);
? ? ? ? ? ? ? ? is = conn.getInputStream();
? ? ? ? ? ? ? ? //將得到的InputStream轉換為字符串
? ? ? ? ? ? ? ? final String str = getStringByInputStream(is);
? ? ? ? ? ? ? ? handler.post(new Runnable() {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? textView.setText(str);
? ? ? ? ? ? ? ? ? ? ? ? btn.setEnabled(true);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? ? ? }catch (Exception e){
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? final String errMessage = e.getMessage();
? ? ? ? ? ? ? ? handler.post(new Runnable() {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? btn.setEnabled(true);
? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, errMessage, Toast.LENGTH_LONG).show();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? ? ? }finally {
? ? ? ? ? ? ? ? if(conn != null){
? ? ? ? ? ? ? ? ? ? conn.disconnect();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
上面的注釋寫的比較詳細,此處我們還是對以上代碼進行一下說明。
首先從asserts目錄中獲取12306.cer證書的文件流,然后用CertificateFactory的generateCertificate方法將該文件流轉化為一個證書對象Certificate,該證書就是12306網站的數字證書。
創建一個默認類型的KeyStore實例,keyStore用于存儲著我們信賴的數字證書,將12306的數字證書放入keyStore中。
我們獲取一個默認的TrustManagerFactory的實例,并用之前的keyStore初始化它,這樣TrustManagerFactory的實例也會信任keyStore中12306.cer證書。通過TrustManagerFactory的getTrustManagers方法獲取TrustManager數組,該數組中的TrustManager也會信任12306.cer證書。
創建一個TLS類型的SSLContext實例,并用之前的TrustManager數組初始化sslContext實例,這樣該sslContext實例也會信任12306.cer證書。
通過sslContext獲取SSLSocketFactory對象,將sslSocketFactory通過setSSLSocketFactory方法作用于HttpsURLConnection對象,這樣conn對象就會信任keyStore中的12306.cer證書。這樣一來,客戶端就會信任12306的證書,從而正確建立HTTPS連接。
以上的處理過程是Google官方建議的流程,步驟流程總結如下:
證書文件流 InputStream -> Certificate -> KeyStore -> TrustManagerFactory -> TrustManager[] -> SSLContext -> SSLSocketFactory -> HttpsURLConnection
以上步驟的起點是獲取證書文件的文件流,不一定非要從assets目錄中獲取,也可以通過其他途徑得到,只要能拿到證書的文件流即可。
上面的過程是對的,但是還存在一點問題。我們將12306網站自身的12306.cer放到了assets目錄中,然后讓我們創建的HttpsURLConnection的實例信任了12306.cer。但是,數字證書都是有過期時間的,如果12306網站的數字證書到期了,那么12306會去SRCA那里重新生成一個數字證書,這時候12306網站的公鑰和私鑰都會更新,那這樣就存在問題了。我們App的assets目錄中存儲的是老的12306.cer證書,這樣12306網站重新生成了新的數字證書,那么老的數字證書就自動作廢了,因為我們App中的12306.cer中的老的公鑰無法解密12306網站最新的私鑰了(公鑰和私鑰只能成對出現,舊的公鑰只能解密舊的私鑰)。
很不幸的是,網上大部分的解決方案就是直接信任12306.cer這種網站自身的數字證書,雖然這種辦法暫時可以解決HTTPS問題,但是不是長久之計,會為以后的數字證書的更新埋下隱患。
那怎么解決這個問題呢?
最好的辦法不是讓我們的App直接信任12306.cer,而是讓我們的App直接信任12306數字證書的簽發者SRCA的數字證書。
我們用之前提到過的辦法將12306的簽發者SRCA的數字證書導出,取名SRCA.cer,將其放到assets目錄下,我們只需要改一行代碼里面的參數即可,我們將代碼:
InputStream cerInputStream = getAssets().open("12306.cer");
1
修成該
InputStream cerInputStream = getAssets().open("SRCA.cer");
1
也就是我們讀取的是SRCA.cer證書的文件流,而不再是12306.cer的。
通過讓HttpsURLConnection實例信任SRCA.cer,也能夠正常建立HTTPS連接,這是為什么呢?
我們之前提到了證書鏈的概念,假設存在如下證書鏈:?
CA -> A -> B -> C
CA是根CA證書,例如SRCA.cer,C是最終的網站的數字證書,例如12306.cer,A和B都是中間證書,理論上來說,只要客戶端信任了該數字證書鏈中的任何一個證書,那么C證書都會被信任。比如客戶端信任了根證書CA,由于CA信任A,所以客戶端也會信任A,由于A信任B,那么客戶端也信任B,由于B信任C,那么客戶端也信任C。所以在12306的例子中,只要信任了SRCA.cer,那么客戶端就信任12306網站自身的12306.cer數字證書了。
Android客戶端不信任服務器證書的原因主要是因為客戶端不信任證書鏈中的根證書CA。12306網站的自身的數字證書可能會過幾年就會重新生成,發生變動,但是SRCA作為其簽發者,發生變動的次數會少的多,或者說是很長時間內不會改動,所以我們的App去信任SRCA.cer比直接去信任12306.cer要更穩定一些。
總結:
HTTPS的傳輸過程涉及到了對稱加密和非對稱加密,對稱加密加密的是實際的數據,非對稱加密加密的是對稱加密所需要的客戶端的密鑰。
為了確保客戶端能夠確認公鑰就是想要訪問的網站的公鑰,引入了數字證書的概念,由于證書存在一級一級的簽發過程,所以就出現了證書鏈,在證書鏈中的頂端的就是根CA。
Android客戶端不信任服務器證書的原因主要是因為客戶端不信任證書鏈中的根證書CA,我們應該讓我們的App去信任該根證書CA,而不是直接信任網站的自身的數字證書,因為網站的數字證書可能會發生變化。
希望本身對大家有所幫助!
參考:?
Limboy的《圖解HTTPS》?
阮一峰的《數字簽名是什么?》?
Google官方的《Security with HTTPS and SSL》
?
總結
以上是生活随笔為你收集整理的Https原理及流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis中对ZSet类型的操作命令
- 下一篇: 10个节省时间和改善工作流的Git技巧