1. 程式人生 > >HTTPS介面加密和身份認證(轉)

HTTPS介面加密和身份認證(轉)

HTTPS介面加密和身份認證

HTTPS研究有一段時間了,在這裡寫下一些收集的資料和自己的理解。有不對的地方希望斧正。

1.為什麼要使用HTTPS代替HTTP

1.1HTTPS和HTTP的區別

  1. https協議需要到CA申請證書,一般免費證書很少,需要交費。
  2. http是超文字傳輸協議,資訊是明文傳輸,https則是具有安全性的SSL加密傳輸協議。
  3. http和https使用的是完全不同的連線方式,用的埠也不一樣,前者是80,後者是443。
  4. http的連線很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路協議,比http協議安全。

1.2 HTTP為什麼不安全

http協議沒有任何的加密以及身份驗證的機制,非常容易遭遇竊聽、劫持、篡改,因此會造成個人隱私洩露,惡意的流量劫持等嚴重的安全問題。

就像寄信一樣,我給你寄信,中間可能會經過很多的郵遞員,他們可以拆開信讀取裡面的內容,因為是明文的。如果你的信裡涉及到了你們銀行賬號等敏感資訊,可能就會被竊取。除此之外,郵遞員們還可以給你偽造信的內容,導致你遭到欺騙。

1.3 HTTPS如何保證安全

HTTPS是以安全為目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。它是一個URI scheme(抽象識別符號體系),句法類同http:體系。用於安全的HTTP資料傳輸。https:URL表明它使用了HTTPS,但HTTPS存在不同於HTTP的預設埠及一個加密/身份驗證層(在HTTP與TCP之間)。這個系統的最初研發由網景公司進行,提供了身份驗證與加密通訊方法,現在它被廣泛用於全球資訊網上安全敏感的通訊,例如交易支付方面。

2.HTTPS的加密原理

2.1首先先介紹一些加密過程中用到的原理:

2.1.1對稱加密

對稱加密是指加密和解密使用相同金鑰的加密演算法。它要求傳送方和接收方在安全通訊之前,商定一個金鑰。對稱演算法的安全性依賴於金鑰,洩漏金鑰就意味著任何人都可以對他們傳送或接收的訊息解密,所以金鑰的保密性對通訊至關重要。

對稱加密演算法的優、缺點:

優點:演算法公開、計算量小、加密速度快、加密效率高。

缺點:

  1. 交易雙方都使用同樣鑰匙,安全性得不到保證;
  2. 每對使用者每次使用對稱加密演算法時,都需要使用其他人不知道的惟一鑰匙,這會使得發收信雙方所擁有的鑰匙數量呈幾何級數增長,金鑰管理成為使用者的負擔。
  3. 能提供機密性,但是不能提供驗證和不可否認性。

2.1.2非對稱加密演算法

這種加密或許理解起來比較困難,這種加密指的是可以生成公鑰和私鑰。凡是公鑰加密的資料,公鑰自身不能解密,而需要私鑰才能解密;凡是私鑰加密的資料,私鑰不能解密,需要公鑰才能解密。這種演算法事實上有很多,常用的是RSA,其基於的數學原理是兩個大素數的乘積很容易算,而拿到這個乘積去算出是哪兩個素數相乘就很複雜了,具體原理有興趣可以自行研究。

非對稱加密相比對稱加密更加安全,但也存在兩個明顯缺點:

  1. CPU計算資源消耗非常大。一次完全TLS握手,金鑰交換時的非對稱解密計算量佔整個握手過程的90%以上。而對稱加密的計算量只相當於非對稱加密的0.1%,如果應用層資料也使用非對稱加解密,效能開銷太大,無法承受。
  2. 非對稱加密演算法對加密內容的長度有限制,不能超過公鑰長度。比如現在常用的公鑰長度是2048位,意味著待加密內容不能超過256個位元組。

所以公鑰加密目前只能用來作金鑰交換或者內容簽名,不適合用來做應用層傳輸內容的加解密。

2.1.3身份認證(CA數字證書)

https協議中身份認證的部分是由數字證書來完成的,證書由公鑰、證書主體、數字簽名等內容組成,在客戶端發起SSL請求後,服務端會將數字證書發給客戶端,客戶端會對證書進行驗證,並獲取用於祕鑰交換的非對稱金鑰。

數字證書有兩個作用:

  1. 身份授權。確保瀏覽器訪問的網站是經過CA驗證的可信任的網站。
  2. 分發公鑰。每個數字證書都包含了註冊者生成的公鑰。在SSL握手時會通過certificate訊息傳輸給客戶端。

申請一個受信任的數字證書通常有如下流程:

  1. 終端實體(可以是一個終端硬體或者網站)生成公私鑰和證書請求。
  2. RA(證書註冊及稽核機構)檢查實體的合法性。如果個人或者小網站,這一步不是必須的。
  3. CA(證書籤發機構)簽發證書,傳送給申請者。
  4. 證書更新到repository(負責數字證書及CRL內容儲存和分發),終端後續從repository更新證書,查詢證書狀態等。

數字證書驗證:

申請者拿到CA的證書並部署在網站伺服器端,那瀏覽器發起握手接收到證書後,如何確認這個證書就是CA簽發的呢?怎樣避免第三方偽造這個證書?答案就是數字簽名(digital signature)。數字簽名是證書的防偽標籤,目前使用最廣泛的SHA-RSA(SHA用於雜湊演算法,RSA用於非對稱加密演算法)數字簽名的製作和驗證過程如下:

  1. 數字簽名的簽發。首先是使用雜湊函式對待簽名內容進行安全雜湊,生成訊息摘要,然後使用CA自己的私鑰對訊息摘要進行加密。
  2. 數字簽名的校驗。使用CA的公鑰解密簽名,然後使用相同的簽名函式對待簽名證書內容進行簽名並和服務端數字簽名裡的簽名內容進行比較,如果相同就認為校驗成功。

image

需要注意的是:

  1. 數字簽名簽發和校驗使用的金鑰對是CA自己的公私金鑰,跟證書申請者提交的公鑰沒有關係。
  2. 數字簽名的簽發過程跟公鑰加密的過程剛好相反,即是用私鑰加密,公鑰解密。
  3. 現在大的CA都會有證書鏈,證書鏈的好處一是安全,保持根CA的私鑰離線使用。第二個好處是方便部署和撤銷,即如果證書出現問題,只需要撤銷相應級別的證書,根證書依然安全。
  4. 根CA證書都是自簽名,即用自己的公鑰和私鑰完成了簽名的製作和驗證。而證書鏈上的證書籤名都是使用上一級證書的金鑰對完成簽名和驗證的。
  5. 怎樣獲取根CA和多級CA的金鑰對?它們是否可信?當然可信,因為這些廠商跟瀏覽器和作業系統都有合作,它們的公鑰都預設裝到了瀏覽器或者作業系統環境裡。

2.2加密的詳細過程

首先伺服器端用非對稱加密(RSA)產生公鑰和私鑰。然後把公鑰發給客 戶端,路徑或許有人會擷取,但是沒有用,因為用公鑰加密的檔案只有私鑰可以解密,而私鑰永遠都不會離開伺服器的。當公鑰到達客戶端之後,客戶端會用對稱加密產生一個祕鑰並且用公鑰來加密傳送給伺服器端,這個祕鑰就是以後用來通訊的鑰匙。這樣伺服器端收到公鑰加密的祕鑰時就可以用私鑰來解公鑰從而獲得祕鑰。這樣的話客戶端和伺服器端都獲得了祕鑰,資訊交流相對是安全的。流程圖如下:

image

聽起來確實是挺安全的,但實際上,還有一種更惡劣的攻擊是這種方法無 法防範的,這就是傳說中的“中間人攻擊”。在身份認證的過程中,出現了一個“中間人”攔截我們的資訊,他有意想要知道你們的訊息。我們將這個中間人稱為M。當伺服器第一次給客戶端傳送公鑰的時候,途徑M。M知道你要進行金鑰交換了,它把公鑰扣了下來,假裝自己是客戶端,偽造了一個偽祕鑰(對稱加密產生的),然後用伺服器發來的公鑰加密了偽祕鑰發還給伺服器,這樣伺服器以為和客戶端完成了金鑰交換,實際上伺服器是和M完成了金鑰交換(獲得了偽祕鑰)。同時M假扮成伺服器自行用非對稱加密產生偽公鑰和偽私鑰,與客戶端進行祕鑰交換,拿到客戶端傳送過來的祕鑰。現在客戶端拿著祕鑰,M拿著祕鑰和為偽祕鑰,伺服器拿著偽祕鑰,整個交流的過程就是:

image

簡單點說就是:

  1. 客戶端用祕鑰加密資訊傳送給M;
  2. M收到後用祕鑰解密拿到資訊,然後用偽祕鑰加密資訊傳送給伺服器;
  3. 伺服器收到後用偽祕鑰解密拿到資訊。

這樣中間人M就拿到了客戶端和伺服器所有的交流資訊。

對於這種攻擊,我們可以加上身份認證:這個時候就要引入CA證書,CA證書的原理可回到2.1.3。數字證書中包括的主要內容有:證書擁有者的個人資訊、證書擁有者的公鑰、公鑰的有效期、頒發數字證書的CA、CA的數字簽名等。所以網上雙方經過相互驗證數字證書後,不用再擔心對方身份的真偽,可以放心地與對方進行交流或授予相應的資源訪問許可權。

通俗一點理解就是,伺服器端把公鑰交個CA證書,CA證書再包裝一層。(具體原理請回看2.3)然後再發給客戶端,這個包裝一層的意思是:保證這個證書是我(伺服器)給你(客戶端的),其他人拿到了也沒有用。

最後,你可能會想既然非對稱加密可以那麼安全,為什麼我們不直接用它來加密資訊,而是用來加密對稱加密的金鑰呢?

這是因為非對稱加密的密碼對生成和加密的消耗時間比較長,為了節省雙方的計算時間,通常只用它來交換金鑰,而非直接用來傳輸資料(具體的可看上文非對稱加密的缺點)。

3.使用AFNetworking進行雙向認證

3.1客戶端認證伺服器端證書

image

如上圖所示客戶端想要認證伺服器,首先需要和服務端的數字證書匹配(server.cer),具體方法如下。

  1. 在專案中匯入證書sever.cer和AFNetworking框架:
  2. 然後到AFSecurityPolicy.m中重寫

  3. 重寫

+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode

方法:

image

AFNetworking2是允許內嵌證書的,通過內嵌證書,AFNetworking2通過比對伺服器端證書、內嵌的證書、站點域名是否一致來驗證連線的伺服器是否正確。在完成以上兩條的情況下,會自動掃描bundle中.cer的檔案,並引入,這樣就可以通過自簽證書來驗證伺服器唯一性了。

3.2伺服器端認證客戶端

  1. 服務端驗證客戶端證書,首先把服務端的證書client.p12匯入到服務端的金鑰庫裡,同時匯入工程;
  2. 在AFURLConnectionOperation.m中加入以下方法:

image

  1. 重寫AFURLConnectionOperation.m中的- (void)connection:(NSURLConnection*)connection

image

如果是需要認證的時候不會先呼叫didReceiveResponse,而是先呼叫3)和2)的函式,NSURLAuthenticationChallenge是一個認證挑戰類,也就是要求客戶端進行挑戰,要接收挑戰也就是客戶端提供挑戰的憑證(使用者和密碼,或者客戶端證書,或者信任伺服器證書,或者代理),IOS提供了一個NSURLCredential的類來表示挑戰憑證。可以通過如下函式來建立挑戰憑證。所以訪問https的時候伺服器認證客戶端就呼叫這個方法。

這兩段程式碼是通過p12檔案來驗證伺服器的,需要自己修改的地方只有一個,那就是2)中的CFStringRefpassword =CFSTR("123456");這是p12證書的密碼,用自己的p12證書密碼替換"123456"

4.3控制器裡如何請求

通過4.1和4.2我們的客戶端和伺服器雙向認證已經設定好了,在控制器裡只需要需要呼叫

manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];

的方法來進行雙向認證:

image

然後就可以訪問HTTPS的伺服器了。

提示:本博文為轉載文章,閱讀原文

關注我