SSL Pinning 和 AFNetworking 2.5.0 的问题(NSURLErrorDomain 错误 -1012。)

Problems with SSL Pinning and AFNetworking 2.5.0 (NSURLErrorDomain error -1012.)

我们一直很难使用 AFNetworking 2.5.0 通过 SSL 保护我们应用程序的网络连接。

我们使用自签名证书颁发机构并使用固定证书实施自定义安全策略。

我们已经测试了 AFNetworking 提供的许多配置,但到目前为止并不幸运。我们收到的错误消息是:

2015-01-05 19:03:07.191 AppName[9301:319051] Error updating user journey. Error: Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x7ae056b0 {NSErrorFailingURLKey=https://api.XXX.com/XXX/XXX/, NSErrorFailingURLStringKey=https://api.XXX.com/XXX/XXX/}

我们的证书在 cURL 和 Android 等其他客户端上运行良好。使用 HTTP 时,我们的实现也能完美运行。

有人知道与固定证书和 AFNetworking 相关的任何问题吗?如果是,我们将不胜感激。

这是实现的一部分:

+ (AFSecurityPolicy*)customSecurityPolicy {
   AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
   NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"der"];
   NSData *certData = [NSData dataWithContentsOfFile:cerPath];
   [securityPolicy setAllowInvalidCertificates:NO];
   [securityPolicy setValidatesCertificateChain:NO];
   [securityPolicy setPinnedCertificates:@[certData]];
   return securityPolicy;
}

+ (AFHTTPRequestOperationManager*)customHttpRequestOperationManager {
   AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
   manager.securityPolicy = [self customSecurityPolicy]; // SSL
   return manager;
}

+(void)getRequestWithUrl:(NSString*)url success:(void(^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void(^) (AFHTTPRequestOperation *operation, NSError *error))failure {
   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
   AFHTTPRequestOperationManager *manager = [HttpClient customHttpRequestOperationManager];
   manager.responseSerializer = [AFHTTPResponseSerializer serializer];
   [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
       [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
       success(operation, responseObject);
   } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
       [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
       failure(operation, error);
   }];
}

谢谢!

您正在创建 AFSecurityPolicy SSLPinningMode 模式 AFSSLPinningModeNone

要使 AFNetworking 信任服务器,固定模式设置为 AFSSLPinningModeNone,您必须将 allowInvalidCertificates 设置为 YES,但这是 相反的 你想要达到的目标。

相反,您应该使用固定模式 AFSSLPinningModeCertificateAFSSLPinningModePublicKey:

创建安全策略
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

阅读完 AFNetworking 代码并检查更改日志后,我必须执行以下操作才能使其正常工作。

使用 AFSSLPinningModeCertificate 创建您的 AFSecurityPolicy 对象:

AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

默认情况下,AFNetworking 将验证证书的域名。我们的证书是在每个服务器的基础上生成的,并不是所有的证书都有域名,所以我们需要禁用它:

[policy setValidatesDomainName:NO];

由于证书是自签名的,从技术上讲它们是 'invalid',所以我们也需要允许:

[policy setAllowInvalidCertificates:YES];

最后,AFNetworking 将尝试在证书链上一直验证证书,在我看来,它似乎只会沿着链向上到达我们的 CA,但无论出于何种原因,它都没有,所以我们有也禁用它:

[policy setValidatesCertificateChain:NO];

就是这样!像您已经在做的那样在您的请求管理器中设置安全策略,它应该可以正常工作。

所以,回顾一下,您发布的代码中真正需要更改的是:

A) 如 David Caunt 所述,将固定模式从 AFSSLPinningModeNone 更改为 AFSSLPinningModeCertificate

B) 添加行以禁用验证域名:[policy setValidatesDomainName:NO]

另外请注意,AFNetworking 现在会自动检查您的捆绑包中是否有 .cer 文件,因此如果您要重命名您的证书以具有 .cer 扩展名,您可以删除代码以从捆绑包中获取证书数据并设置固定的证书。

处理过类似的问题后,通过浏览器 HTTPS 连接看起来正常的情况很常见,因为许多浏览器缓存来自第三方的证书文件,因此并不总是需要加载它们。因此,很可能您的证书链并不像您被引导相信的那样完全受信任。

换句话说,与浏览器安全连接似乎没问题,但根据您的 AFNetworking 设置,您的应用实际上不会接受您的证书链。在确定您的设置合适之后,下一步就是确保您的证书链确实如您所想的那样好。下载名为 SSL Detective 的应用程序并查询您的服务器。您也可以使用 www.ssldecoder.org。确保您的链中没有红色(不受信任的)项目。如果有,请更改服务器上的证书设置。

鉴于您的AFNetworking设置如下:

 [securityPolicy setAllowInvalidCertificates:NO];
 [securityPolicy setValidatesCertificateChain:NO];

它可能不喜欢您的证书链,因为它是自签名的。您可能还必须将它们切换为“是”。

我遇到了这个错误,Error Domain=NSURLErrorDomain Code=-1012 NSErrorFailingURLStringKey

仅以下更改就让它对我有用。

self.validatesDomainName = NO;

既然你已经初始化了管理器,你可以这样做:

manager.securityPolicy.allowInvalidCertificates = YES;
manager.securityPolicy.validatesDomainName = NO;

它适用于自签名证书

我尝试了所有这些但没有任何帮助,然后我搜索了这一行

'NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");'

在这条线下面我更改了

'return NO;'

'return YES;'

它真的很神奇。

谢谢。

- (AFSecurityPolicy *)securityPolicy {
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"*.something.co.in" ofType:@"cer"];
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    [securityPolicy setAllowInvalidCertificates:YES];
    [securityPolicy setPinnedCertificates:@[certData]];
    [securityPolicy setValidatesDomainName:NO];
    [securityPolicy setValidatesCertificateChain:NO];
    return securityPolicy;
}

出于某种原因,这对我有用。仍然不确定这会如何改变事情,因为我的应用程序中的其他连接无需执行所有这些步骤即可工作。

这是生成安全策略的错误的样子 -

- (AFSecurityPolicy *)securityPolicy {
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"*.something.co.in" ofType:@"cer"];
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    [securityPolicy setAllowInvalidCertificates:NO];
    [securityPolicy setPinnedCertificates:@[certData]];
    [securityPolicy setValidatesDomainName:YES];
    return securityPolicy;
}

现在遵守 "Don't fix if it ain't broken" 规则

对我来说,我在我的 Podfile 中设置了 use_frameworks! - 该项目没有使用 Swift,我使用 Pods 作为 [=13] =].对此发表评论,为我解决了这个问题。

如果您只是想在没有客户端证书的情况下使警告静音,策略应如下所示:

AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
[policy setValidatesDomainName:YES];
[policy setAllowInvalidCertificates:NO];