2016-05-23 85 views
2

我正在使用AFNetworking 3.0。我有一個由Global Sign簽名的https證書的webserver。我想添加證書鎖定到我的iOS應用程序。我的代碼如下:使用AFNetworking 3.0 SSL固定

- (AFSecurityPolicy*)customSecurityPolicy{ 

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; 
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"]; 
NSData *certData = [NSData dataWithContentsOfFile:cerPath]; 
[securityPolicy setAllowInvalidCertificates:NO]; 
[securityPolicy setValidatesDomainName:YES]; 

//securityPolicy.validatesCertificateChain = NO; 
[securityPolicy setPinnedCertificates:[NSKeyedUnarchiver unarchiveObjectWithData:certData]]; 

return securityPolicy; 
} 

我的客戶端代碼:

NSString *url = SERVER_URL; 
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"]; 
manager.securityPolicy = [utils customSecurityPolicy]; 
[manager GET:url parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) { 

    NSLog(@"JSON: %@", responseObject); 


} failure:^(NSURLSessionTask *operation, NSError *error) { 
    NSLog(@"Error: %@", error); 

}]; 

我們使用打嗝套房的人在這方面的中間人代理,我們可以中斷請求和監測的內容請求。

那麼,如何正確實施證書鎖定?

回答

1

這是AFNetworking以外的有效問題,您發現的唯一的事情是您正在使用的庫實現curl --cacert操作的方式。

AFNetworking的特定情況下,我有這種情況:

let sessionManager = AFHTTPSessionManager() 
sessionManager.responseSerializer = AFJSONResponseSerializer() 
sessionManager.requestSerializer = AFJSONRequestSerializer() 
let configuration = ServiceConfiguration.sharedInstance.configuration 
if let policy = configuration?.getSecurityPolicy()?.policy() as? AFSecurityPolicy { 
    sessionManager.securityPolicy = policy 
} 

getSecurityPolicy方法返回的RequestSecurityPolicy的可選對象(即一個協議)。

若要使AFSecurityPolicy我:

import AFNetworking 

class SSLPinningPolicy: NSObject, RequestSecurityPolicy { 

    // MARK: - Private properties - 

    private var certificatesDictionary: [String: Data] = [:] 

    // MARK: - Initilizers - 

    init(certicatePaths: [String]) { 
     super.init() 
     for path in certicatePaths { 
      if let certPath = Bundle.main.path(forResource: path, ofType: "der") { 
       let url = URL(fileURLWithPath: certPath) 
       do { 
        let data = try Data(contentsOf: url) 
        self.certificatesDictionary[path] = data 
       } catch { 

       } 
      } 
     } 
    } 

    // MARK: - RequestSecurityPolicy delegates - 

    func policy() -> AnyObject { 
     let policy = AFSecurityPolicy(pinningMode: .certificate) 
     policy.allowInvalidCertificates = true 
     policy.pinnedCertificates = self.certificates() 
     return policy 
    } 

    func certificates() -> Set<Data> { 
     return Set(self.certificatesDictionary.map { $0.value }) 
    } 

} 

爲了我的證書轉換從.pem.der你可以簡單地使用OpenSSL的在你的shell:

openssl x509 -outform der -in MyCertificate.pem -out MyCertificate.der