iOS適配HTTPS,創建一個自簽名的SSL證書(x509)具體步驟


iOS適配HTTPS,創建一個自簽名的SSL證書(x509)具體步驟

 

引言(創建生成的證書只能用於測試使用。如果想使用自簽名證書就只能以自己為 CA機構頒發證書,進行雙向認證才能使用)

使用HTTP(超文本傳輸)協議訪問互聯網上的數據是沒有經過加密的。也就是說,任何人都可以通過適當的工具攔截或者監聽到在網絡上傳輸的數據流。但是有時候,我們需要在網絡上傳輸一些安全性或者私秘性的數據,譬如:包含信用卡及商品信息的電子訂單。這個時候,如果仍然使用HTTP協議,勢必會面臨非常大的風險!相信沒有人能接受自己的信用卡號在互聯網上裸奔。

HTTPS(超文本傳輸安全)協議無疑可以有效的解決這一問題。所謂HTTPS,其實就是HTTP和SSL/TLS的組合,用以提供加密通訊及對網絡服務器的身份鑒定。HTTPS的主要思想是在不安全的網絡上創建一安全信道,防止黑客的竊聽和攻擊。

SSL(安全套接層)可以用來對Web服務器和客戶端之間的數據流進行加密。

SSL利用非對稱密碼技術進行數據加密。加密過程中使用到兩個秘鑰:一個公鑰和一個與之對應的私鑰。使用公鑰加密的數據,只能用與之對應的私鑰解密;而使用私鑰加密的數據,也只能用與之對應的公鑰解密。因此,如果在網絡上傳輸的消息或數據流是被服務器的私鑰加密的,則只能使用與其對應的公鑰解密,從而可以保證客戶端與與服務器之間的數據安全。

數字證書(Certificate)

在HTTPS的傳輸過程中,有一個非常關鍵的角色——數字證書,那什么是數字證書?又有什么作用呢?

所謂數字證書,是一種用於電腦的身份識別機制。由數字證書頒發機構(CA)對使用私鑰創建的簽名請求文件做的簽名(蓋章),表示CA結構對證書持有者的認可。數字證書擁有以下幾個優點:

  1. 使用數字證書能夠提高用戶的可信度
  2. 數字證書中的公鑰,能夠與服務端的私鑰配對使用,實現數據傳輸過程中的加密和解密
  3. 在證認使用者身份期間,使用者的敏感個人數據並不會被傳輸至證書持有者的網絡系統上

X.509證書包含三個文件:key,csr,crt。

  • key是服務器上的私鑰文件,用於對發送給客戶端數據的加密,以及對從客戶端接收到數據的解密
  • csr是證書簽名請求文件,用於提交給證書頒發機構(CA)對證書簽名
  • crt是由證書頒發機構(CA)簽名后的證書,或者是開發者自簽名的證書,包含證書持有人的信息,持有人的公鑰,以及簽署者的簽名等信息

備注:在密碼學中,X.509是一個標准,規范了公開秘鑰認證、證書吊銷列表、授權憑證、憑證路徑驗證算法等。

創建自簽名證書的步驟

注意:以下步驟僅用於配置內部使用或測試需要的SSL證書。如果想生成雙向認證證書請參考:http://www.2cto.com/article/201411/347512.html里面證書的制作

第1步:生成私鑰

使用openssl工具生成一個RSA私鑰

說明:生成rsa私鑰,des3算法,2048位強度,server.key是秘鑰文件名。

注意:生成私鑰,需要提供一個至少4位的密碼。

第2步:生成CSR(證書簽名請求)

生成私鑰之后,便可以創建csr文件了。

此時可以有兩種選擇。理想情況下,可以將證書發送給證書頒發機構(CA),CA驗證過請求者的身份之后,會出具簽名證書(很貴)。另外,如果只是內部或者測試需求,也可以使用OpenSSL實現自簽名,具體操作如下:

說明:需要依次輸入國家,地區,城市,組織,組織單位,Common Name和Email。其中Common Name,可以寫自己的名字或者域名,如果要支持https,Common Name應該與域名保持一致,否則會引起瀏覽器警告。

 

第3步:刪除私鑰中的密碼

在第1步創建私鑰的過程中,由於必須要指定一個密碼。而這個密碼會帶來一個副作用,那就是在每次Apache啟動Web服務器時,都會要求輸入密碼,這顯然非常不方便。要刪除私鑰中的密碼,操作如下:

 

第4步:生成自簽名證書

如果你不想花錢讓CA簽名,或者只是測試SSL的具體實現。那么,現在便可以着手生成一個自簽名的證書了。

需要注意的是,在使用自簽名的臨時證書時,瀏覽器會提示證書的頒發機構是未知的。

說明:crt上有證書持有人的信息,持有人的公鑰,以及簽署者的簽名等信息。當用戶安裝了證書之后,便意味着信任了這份證書,同時擁有了其中的公鑰。證書上會說明用途,例如服務器認證,客戶端認證,或者簽署其他證書。當系統收到一份新的證書的時候,證書會說明,是由誰簽署的。如果這個簽署者確實可以簽署其他證書,並且收到證書上的簽名和簽署者的公鑰可以對上的時候,系統就自動信任新的證書。

第5步:安裝私鑰和證書

將私鑰和證書文件復制到Apache的配置目錄下即可,在Mac 10.10系統中,復制到/etc/apache2/目錄中即可。

 

第6步:客戶端利用AF3.0使用自定義證書

1.

復制代碼
// 1.初始化單例類
     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.securityPolicy.SSLPinningMode = AFSSLPinningModeCertificate;
    // 2.設置證書模式
    NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"cer"];
    NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
    manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:cerData, nil]];
    // 客戶端是否信任非法證書
    mgr.securityPolicy.allowInvalidCertificates = YES;
    // 是否在證書域字段中驗證域名
    [mgr.securityPolicy setValidatesDomainName:NO];
復制代碼

2.使用AFNetworking進行請求

AFNetworking首先需要配置AFSecurityPolicy類,AFSecurityPolicy類封裝了證書校驗的過程。

復制代碼
/**
 AFSecurityPolicy分三種驗證模式:
 AFSSLPinningModeNone:只是驗證證書是否在信任列表中
 AFSSLPinningModeCertificate:該模式會驗證證書是否在信任列表中,然后再對比服務端證書和客戶端證書是否一致
 AFSSLPinningModePublicKey:只驗證服務端證書與客戶端證書的公鑰是否一致
*/
 
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    securityPolicy.allowInvalidCertificates = YES;//是否允許使用自簽名證書
    securityPolicy.validatesDomainName = NO;//是否需要驗證域名,默認YES
 
    AFHTTPSessionManager *_manager = [AFHTTPSessionManager manager];
    _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    _manager.securityPolicy = securityPolicy;
    //設置超時
    [_manager.requestSerializer willChangeValueForKey:@"timeoutinterval"];
    _manager.requestSerializer.timeoutInterval = 20.f;
    [_manager.requestSerializer didChangeValueForKey:@"timeoutinterval"];
    _manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData;
    _manager.responseSerializer.acceptableContentTypes  = [NSSet setWithObjects:@"application/xml",@"text/xml",@"text/plain",@"application/json",nil];
  
    __weak typeof(self) weakSelf = self;
    [_manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *_credential) {
         
        SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
        /**
         *  導入多張CA證書
         */
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"cer"];//自簽名證書
        NSData* caCert = [NSData dataWithContentsOfFile:cerPath];
        NSArray *cerArray = @[caCert];
        weakSelf.manager.securityPolicy.pinnedCertificates = cerArray;
         
        SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);
        NSCAssert(caRef != nil, @"caRef is nil");
         
        NSArray *caArray = @[(__bridge id)(caRef)];
        NSCAssert(caArray != nil, @"caArray is nil");
         
        OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
        SecTrustSetAnchorCertificatesOnly(serverTrust,NO);
        NSCAssert(errSecSuccess == status, @"SecTrustSetAnchorCertificates failed");
         
        NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        __autoreleasing NSURLCredential *credential = nil;
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            if ([weakSelf.manager.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
                credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                if (credential) {
                    disposition = NSURLSessionAuthChallengeUseCredential;
                } else {
                    disposition = NSURLSessionAuthChallengePerformDefaultHandling;
                }
            } else {
                disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
            }
        } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
         
        return disposition;
    }];
復制代碼

上述代碼通過給AFHTTPSessionManager重新設置證書驗證回調來自己驗證證書,然后將自己的證書加入到可信任的證書列表中,即可通過證書的校驗。


免責聲明!

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



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