HTTPS的學習


HTTPS的學習總結

 

HTTPS學習總結

簡述

HTTPS對比HTTP就多了一個安全層SSL/TLS,具體就是驗證服務端的證書和對內容進行加密。

先來看看HTTP和HTTPS的區別 
我用AFN訪問http下的httpbin.org/image/png 
然后用Charles抓一下包,可以看到傳輸的圖片 
http的數據
然后訪問HTTPS下的https://httpbin.org/image/png 
再抓包,看到數據是亂碼,這就是加密過后的數據 
https的數據

關於加密算法

1)對稱加密:密鑰只有一個,加密解密為同一個密碼,且加解密速度快,典型的對稱加密算法有DES、AES等;

2)非對稱加密:非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數據進行加密,那么只有用對應的公開密鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。

過程就像我們用github的時候也是這樣,我們電腦這里生成私鑰和公鑰,公鑰上傳到github,私鑰添加到我們電腦的ssh里,這樣github給我們傳輸數據就是用我們上傳的公鑰來加密,我們獲得數據后會用私鑰去解密。

什么是SSL/TLS

TLS是 Transport Layer Security的縮寫,傳輸層安全性協議,SSL是Secure Sockets Layer的縮寫,安全sokects層協議。SSL/TLS有很多好處,強大的驗證,算法靈活,容易部署和使用。缺點是增加處理器的負擔,但是消耗的性能很小,對比安全性來說可以忽略不計。

通信過程

通信過程有四次握手。 
1、客戶端發送請求,服務器返回公鑰給客戶端; 
2、客戶端生成對稱加密秘鑰,用公鑰對其進行加密后,返回給服務器; 
3、服務器收到后,利用私鑰解開得到對稱加密秘鑰,保存; 
4、之后的交互都使用對稱加密后的數據進行交互。

HTTPS通信的優點 
1)客戶端產生的密鑰只有客戶端和服務器端能得到;

2)加密的數據只有客戶端和服務器端才能得到明文;

3)客戶端到服務端的通信是安全的。

如何獲得證書

1.向CA申請證書

電子商務認證授權機構(CA, Certificate Authority),也稱為電子商務認證中心,是負責發放和管理數字證書的權威機構。 
這里就不細說了。

2.自制證書

還有一種方式就是自制證書,自制證書的證書是用OpenSSL生成的。OpenSSL 是一個強大的安全套接字層密碼庫,囊括主要的密碼算法、常用的密鑰和證書封裝管理功能及SSL協議,並且已經在github上開源。

OpenSSL的各種指令 
OpenSSL

自制證書的命令是

1
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX

剛開始輸入命令就會自動生成key.pem 
輸入命令后會讓你輸入密碼、國家、省市、組織(公司)、名字等信息 
輸入完成便會生成證書cert.pem

關於命令的一些選項:

  • req 是證書請求和生成的程序
  • -x509 一種證書標准
  • -newkey arg,arg是參數,例如rsa:2048是指生成2048位的rsa key
  • -keyout filename 輸出的根證書文件名
  • -out filename 輸出的標准證書文件嗎
  • -day n 用X.509標准的話要指定驗證多少天,默認30
  • *

預覽cert.pem可以看到剛才輸入的信息 
預覽pem

pem可以轉換成cer格式,可以用命令
1
openssl x509 -in <你的服務器證書>.pem -outform der -out server.cer

也可以雙擊 cert.pem,這樣是導入到鑰匙串,打開鑰匙串便可導出cer格式的證書。

以上 部分自制證書資料參考的是stackoverflow的這個問題

關於Security框架

看了一下蘋果的官方文檔,Security框架是C語言寫的,提供了一些管理標識碼,證書,數字簽名,信任等的API。 
這里介紹一下幾個常用的對象。SecIdentityRef 代碼一個標識碼對象,struct類型,包含一個SecKeyRef類型和一個SecCertificateRef類型。SecKeyRef就是一個非對稱的key對象。SecCertificateRef是一個遵循X.509標准的證書對象。如果這兩個對象沒有存儲到keychain中,則會把它們轉換成SecKeychainItemRef對象還會使Keychain Services的函數返回錯誤。

要生成p12證書,這讓我想起配置推送證書的時候,導出證書的時候便是把cer格式的證書轉換成p12格式的證書。

iOS實現HTTPS傳輸

因為項目都是用AFN,所以就大概說下AFN的實現方法 
如果是CA認證的證書,則直接用AFN請求便可。

1
2
3
4
5
6
7
8
9
10
11
AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
 
//allowInvalidCertificates 是否允許無效證書(也就是自建的證書),默認為NO
//如果是需要驗證自建證書,需要設置為YES
securityPolicy.allowInvalidCertificates =  YES ;
 
//validatesDomainName 是否需要驗證域名,默認為YES;
//假如證書的域名與你請求的域名不一致,需把該項設置為NO;如設成NO的話,即服務器使用其他可信任機構頒發的證書,也可以建立連接,這個非常危險,建議打開。
//置為NO,主要用於這種情況:客戶端請求的是子域名,而證書上的是另外一個域名。因為SSL證書上的域名是獨立的,假如證書上注冊的域名是www.google.com,那么mail.google.com是無法驗證通過的;當然,有錢可以注冊通配符的域名*.google.com,但這個還是比較貴的。
//如置為NO,建議自己添加對應域名的校驗邏輯。
securityPolicy.validatesDomainName =  YES ;

  

如果是自制證書,則客戶端需要導入服務端的公鑰,把公鑰拖進Xocde里,這里要用到把證書從pem轉換成p12格式,參見上面的方法 
2.修改驗證方式

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
- ( void )testClientCertificate {
   SecIdentityRef identity =  NULL ;
   SecTrustRef trust =  NULL ;
   NSString  *p12 = [[ NSBundle  mainBundle] pathForResource:@ "testClient"  ofType:@ "p12" ];
   NSData  *PKCS12Data = [ NSData  dataWithContentsOfFile:p12];
 
   [[ self  class ] extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];
 
   NSDictionary  *dic = @{@ "request"  : @{
                             @ "orderNo"  : @ "1409282102222110030643" ,
                             @ "type"  : @(2)
                             }
                         };
 
   _signString =  nil ;
   NSData  *postData = [ NSJSONSerialization  dataWithJSONObject:dic
                                                      options: NSJSONWritingPrettyPrinted
                                                        error: nil ];
   NSString  *sign = [ self  signWithSignKey:@ "test"  params:dic];
   NSMutableData  *body = [postData mutableCopy];
   NSLog (@ "%@" , [[ NSString  alloc] initWithData:body encoding: NSUTF8StringEncoding ]);
   url = [ NSString  stringWithFormat:url, sign];
 
   AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
   manager.requestSerializer = [AFJSONRequestSerializer serializer];
   manager.responseSerializer = [AFJSONResponseSerializer serializer];
   [manager.requestSerializer setValue:@ "application/json"  forHTTPHeaderField:@ "Accept" ];
   [manager.requestSerializer setValue:@ "application/json"  forHTTPHeaderField:@ "Content-Type" ];
   manager.responseSerializer.acceptableContentTypes = [ NSSet  setWithArray:@[@ "application/json" ,
                                                                             @ "text/plain" ]];
   manager.securityPolicy = [ self  customSecurityPolicy];
 
   [manager POST:url parameters:dic success:^(AFHTTPRequestOperation *operation,  id  responseObject) {
     NSLog (@ "JSON: %@" , responseObject);
   } failure:^(AFHTTPRequestOperation *operation,  NSError  *error) {
 
     NSLog (@ "Error: %@" , error);
   }];
}
 
// 下面這段代碼是處理SSL安全性問題的:
/**** SSL Pinning ****/
- (AFSecurityPolicy*)customSecurityPolicy {
   NSString  *cerPath = [[ NSBundle  mainBundle] pathForResource:@ "testClient"  ofType:@ "cer" ];
   NSData  *certData = [ NSData  dataWithContentsOfFile:cerPath];
   AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
   [securityPolicy setAllowInvalidCertificates: YES ];
   [securityPolicy setPinnedCertificates:@[certData]];
   [securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];
   /**** SSL Pinning ****/
   return  securityPolicy;
}

  

這段代碼來自參考資料3,寫的很好,沒必要再說一次了

總結

在現在網絡越來越發達的情況下,安全性越來越重要。不多說,https是趨勢。

參考資料: 
1.聊聊 iOS 中的網絡加密 / 滕先洪

2.iOS安全系列之一:HTTPS / Jaminzzhang

3.iOS訪問HTTPS SSL和TLS雙向加密 / 標哥的技術博客

4.蘋果相關官方文檔

 
 
標簽:  我的學習HTTPS


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM