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
,但这是 相反的 你想要达到的目标。
相反,您应该使用固定模式 AFSSLPinningModeCertificate
或 AFSSLPinningModePublicKey
:
创建安全策略
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];
我们一直很难使用 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
,但这是 相反的 你想要达到的目标。
相反,您应该使用固定模式 AFSSLPinningModeCertificate
或 AFSSLPinningModePublicKey
:
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];