標籤:資料安全 syntax /etc/ manage methods 用戶端 data- 訪問 highlight
引言(建立產生的認證只能用於測試使用。如果想使用自我簽署憑證就只能以自己為 CA機構頒發認證,進行雙向認證才能使用)
使用HTTP(超文本傳輸)協議訪問互連網上的資料是沒有經過加密的。也就是說,任何人都可以通過適當的工具攔截或者監聽到在網路上傳輸的資料流。但是有時候,我們需要在網路上傳輸一些安全性或者私秘性的資料,譬如:包含信用卡及商品資訊的電子訂單。這個時候,如果仍然使用HTTP協議,勢必會面臨非常大的風險!相信沒有人能接受自己的信用卡號在互連網上裸奔。
HTTPS(超文本傳輸安全)協議無疑可以有效解決這一問題。所謂HTTPS,其實就是HTTP和SSL/TLS的組合,用以提供加密通訊及對網路伺服器的身份評鑑。HTTPS的主要思想是在不安全的網路上建立一安全通道,防止駭客的竊聽和攻擊。
SSL(安全套接層)可以用來對Web伺服器和用戶端之間的資料流進行加密。
SSL利用非對稱密碼技術進行資料加密。加密過程中使用到兩個秘鑰:一個公開金鑰和一個與之對應的私密金鑰。使用公開金鑰加密的資料,只能用與之對應的私密金鑰解密;而使用私密金鑰加密的資料,也只能用與之對應的公開金鑰解密。因此,如果在網路上傳輸的訊息或資料流是被伺服器的私密金鑰加密的,則只能使用與其對應的公開金鑰解密,從而可以保證用戶端與與伺服器之間的資料安全。
數位憑證(Certificate)
在HTTPS的傳輸過程中,有一個非常關鍵的角色——數位憑證,那什麼是數位憑證?又有什麼作用呢?
所謂數位憑證,是一種用於電腦的身份識別機制。由數位憑證頒發機構(CA)對使用私密金鑰建立的簽章要求檔案做的簽名(蓋章),表示CA結構對認證持有人的認可。數位憑證擁有以下幾個優點:
- 使用數位憑證能夠提高使用者的可信度
- 數位憑證中的公開金鑰,能夠與服務端的私密金鑰配對使用,實現資料轉送過程中的加密和解密
- 在證認使用者身份期間,使用者的敏感個人資料並不會被傳輸至認證持有人的網路系統上
X.509認證包含三個檔案:key,csr,crt。
- key是伺服器上的私密金鑰檔案,用於對發送給用戶端資料的加密,以及對從用戶端接收到資料的解密
- csr是認證簽章要求檔案,用於提交給憑證授權單位(CA)對認證簽名
- crt是由憑證授權單位(CA)簽名後的認證,或者是開發人員自簽名的認證,包含認證持有人的資訊,持有人的公開金鑰,以及簽署者的簽名等資訊
備忘:在密碼學中,X.509是一個標準,規範了公開秘鑰認證、憑證撤銷清單、授權憑證、憑證路徑驗證演算法等。
建立自我簽署憑證的步驟
注意:以下步驟僅用於配置內部使用或測試需要的SSL認證。如果想產生雙向認證認證請參考:http://www.2cto.com/article/201411/347512.html裡面認證的製作
第1步:產生私密金鑰
使用openssl工具產生一個RSA私密金鑰
| 1 |
$ openssl genrsa -des3 -out server.key 2048 |
說明:產生rsa私密金鑰,des3演算法,2048位強度,server.key是秘鑰檔案名稱。
注意:產生私密金鑰,需要提供一個至少4位的密碼。
第2步:產生CSR(認證簽章要求)
產生私密金鑰之後,便可以建立csr檔案了。
此時可以有兩種選擇。理想情況下,可以將認證發送給憑證授權單位(CA),CA驗證過要求者的身份之後,會出具簽署憑證(很貴)。另外,如果只是內部或者測試需求,也可以使用OpenSSL實現自簽名,具體操作如下:
| 1 |
$ openssl req -new -key server.key -out server.csr |
說明:需要依次輸入國家,地區,城市,組織,組織單位,Common Name和Email。其中Common Name,可以寫自己的名字或者網域名稱,如果要支援https,Common Name應該與網域名稱保持一致,否則會引起瀏覽器警告。
| 1234567 |
Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:BeijingLocality Name (eg, city) []:BeijingOrganization Name (eg, company) [Internet Widgits Pty Ltd]:joyiosOrganizational Unit Name (eg, section) []:info technologyCommon Name (e.g. server FQDN or YOUR name) []:demo.joyios.comEmail Address []:liufan@joyios.com |
第3步:刪除私密金鑰中的密碼
在第1步建立私密金鑰的過程中,由於必須要指定一個密碼。而這個密碼會帶來一個副作用,那就是在每次Apache啟動Web伺服器時,都會要求輸入密碼,這顯然非常不方便。要刪除私密金鑰中的密碼,操作如下:
| 12 |
cp server.key server.key.orgopenssl rsa -in server.key.org -out server.key |
第4步:產生自我簽署憑證
如果你不想花錢讓CA簽名,或者只是測試SSL的具體實現。那麼,現在便可以著手產生一個自簽名的認證了。
需要注意的是,在使用自簽名的臨時認證時,瀏覽器會提示認證的頒發機構是未知的。
| 1 |
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt |
說明: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重新設定認證驗證回調來自己驗證認證,然後將自己的認證加入到可信任的認證列表中,即可通過認證的校正。
iOS適配HTTPS,建立一個自簽名的SSL認證(x509)具體步驟