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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27808249/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 04:15:38  来源:igfitidea点击:

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

iossslafnetworkingafnetworking-2

提问by davhab

We've been having a hard time securing our app's network connections with SSL using AFNetworking 2.5.0.

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

We use a self-signed certificate authority and implemented a custom security policy using pinned certificates.

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

We've tested quite a few configurations provided by AFNetworking but have not been lucky so far. The error message we receive is:

我们已经测试了很多 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/}

2015-01-05 19:03:07.191 AppName[9301:319051] 更新用户旅程时出错。错误:Error Domain=NSURLErrorDomain Code=-1012 “操作无法完成。(NSURLErrorDomain 错误 -1012。)” UserInfo=0x7ae056b0 {NSErrorFailingURLKey= https://api.XXX.com/XXX/XXX/, NSErrorFailingURLStringKey= https://api.XXX.com/XXX/XXX/}

Our certificate works fine on other clients such as cURL and Android. When using HTTP, our implementation works perfectly fine too.

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

Is anyone aware of any issues related to pinned certificates and AFNetworking? If yes, we'd appreciate any pointers you may have.

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

Here's part of the implementation:

这是实现的一部分:

+ (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);
   }];
}

Thank you!

谢谢!

回答by Jordan Bondo

After reading through the AFNetworking code & and checking the change logs, here's what I had to do to get this working.

在通读 AFNetworking 代码 & 并检查更改日志后,这是我必须做的才能使其正常工作。

Create your AFSecurityPolicy object with AFSSLPinningModeCertificate:

使用 AFSSLPinningModeCertificate 创建您的 AFSecurityPolicy 对象:

AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

By default, AFNetworking will validate the domain name of the certificate. Our certificates are generated on a per-server basis, and not all of them will have a domain name, so we need to disable that:

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

[policy setValidatesDomainName:NO];

Since the certificates are self-signed, they are technically 'invalid', so we need to allow that as well:

由于证书是自签名的,因此它们在技术上是“无效的”,因此我们也需要允许:

[policy setAllowInvalidCertificates:YES];

Lastly, AFNetworking will attempt to validate the certificate all the way up the certificate chain, which to me seems like it would only go up the chain to OUR CA, but for whatever reason it doesn't, so we have to disable that too:

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

[policy setValidatesCertificateChain:NO];

And that's it! Set the security policy in your request manager like you're already doing and it should work fine.

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

So, recap, all you really need to change in the code you posted is this:

因此,回顾一下,您真正​​需要在您发布的代码中更改的是:

A) As David Cauntmentioned, change your pinning mode from AFSSLPinningModeNoneto AFSSLPinningModeCertificate

A) 正如David Caunt提到的,将您的固定模式从 更改AFSSLPinningModeNoneAFSSLPinningModeCertificate

and

B) Add the line to disable validating the domain name: [policy setValidatesDomainName:NO]

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

Another note, AFNetworking now automatically checks your bundle for .cer files, so if you were to rename your certificate to have a .cer extension, you can eliminate the code to get the certificate data out of the bundle and set the pinned certificates.

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

回答by Even Cheng

since you have manager initialized, you can do:

由于您已初始化经理,您可以执行以下操作:

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

and it will work for a self-signed certificate

它适用于自签名证书

回答by thatzprem

I was getting this error, Error Domain=NSURLErrorDomain Code=-1012 NSErrorFailingURLStringKey

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

The below change alone got it working for me.

仅以下更改就让它为我工作。

self.validatesDomainName = NO;

回答by David Snabel-Caunt

You're creating an AFSecurityPolicywith SSLPinningModemode AFSSLPinningModeNone.

您正在创建一个AFSecurityPolicywithSSLPinningMode模式AFSSLPinningModeNone

For AFNetworking to trust the server, with pinning mode set to AFSSLPinningModeNone, you must set allowInvalidCertificatesto YES, but this is the oppositeof what you are trying to achieve.

要使 AFNetworking 信任服务器,将固定模式设置为AFSSLPinningModeNone,您必须设置allowInvalidCertificatesYES,但这您要实现的目标相反

Instead, you should create your security policy with pinning mode AFSSLPinningModeCertificateor AFSSLPinningModePublicKey:

相反,您应该使用固定模式AFSSLPinningModeCertificateAFSSLPinningModePublicKey以下方式创建安全策略:

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

回答by genaks

- (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;
}

This worked for me for some reason. Still not sure how this changes things because other connections in my app work without taking all these steps.

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

This is what the error generating security policy looks like -

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

- (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;
}

Now sticking to the "Don't fix if it ain't broken" rule

现在坚持“如果它没有坏就不要修复”规则

回答by Robert J. Clegg

For me, I had use_frameworks!set in my Podfile- the project doesn't make user of Swift and I was using Podsfor AFNetworking. Commenting this out, fixed the issue for me.

对我来说,我已经use_frameworks!在我Podfile的项目中设置了- 该项目不会使 Swift 成为用户,而我使用的是Podsfor AFNetworking. 对此发表评论,为我解决了问题。

回答by thomas gotzsche

If you just want to silence the warning without having a client certificate, the policy should look like this:

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

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

回答by Marcel

Having dealt with a similar issue, it is common for things seem normal via browser HTTPS connections, as many browsers cache certificate files from third parties so that they don't always need to be loaded. Therefore, it could very well be that your certificate chain is not fully trusted as you may have been led to believe.

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

In other words, it may seem fine to connect securely with a browser, but depending on your AFNetworking settings, your app won't actually accept your certificate chain. After you are sure your settings are appropriate, the next step is to make sure your certificate chain is actually as good as you think it is. Download an app called SSL Detective and query your server. You can also use www.ssldecoder.org. Make sure there are no red (untrusted) items in your chain. If there are, change your cert setup on the server.

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

Given that your AFNetworking settings are as follows:

鉴于您的 AFNetworking 设置如下:

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

It may not like your certificate chain because it is self signed. You might also have to switch those to YES.

它可能不喜欢您的证书链,因为它是自签名的。您可能还需要将它们切换为 YES。

回答by Naveed Rafi

I tried all of these but nothing helped then I searched for this line

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

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

'NSLog(@"为了验证自签名证书的域名,您必须使用固定。");'

and below this line I changed

在这条线下面我改变了

'return NO;'
to

'返回NO;'

'return YES;'

'返回是;'

and it did the magic.

它发挥了神奇的作用。

Thanks.

谢谢。