Ios 使用AFX27的SSL固定;行不通

Ios 使用AFX27的SSL固定;行不通,ios,objective-c,ssl,afnetworking,pinning,Ios,Objective C,Ssl,Afnetworking,Pinning,我正在尝试使用自签名证书将SSL固定添加到我的应用程序中,但似乎无法使其正常工作。 我尝试了在互联网上能找到的一切,但都没有成功,而不是SSL工作原理方面的专家也无济于事 我正在使用objective-c和最新版本的AFNetworking 我编写了一段非常简单的代码来测试我的API调用(我在这篇文章中使用了一个占位符URL): NSString*url=@”https://api.example.net/webservice"; NSString*cerPath=[[NSBundle main

我正在尝试使用自签名证书将SSL固定添加到我的应用程序中,但似乎无法使其正常工作。 我尝试了在互联网上能找到的一切,但都没有成功,而不是SSL工作原理方面的专家也无济于事

我正在使用objective-c和最新版本的AFNetworking

我编写了一段非常简单的代码来测试我的API调用(我在这篇文章中使用了一个占位符URL):

NSString*url=@”https://api.example.net/webservice";
NSString*cerPath=[[NSBundle mainBundle]pathForResource:@“example.net”,类型:@“der”];
NSData*certData=[NSData dataWithContentsOfFile:cerPath];
AFHTTPSessionManager*manager=[[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:url]];
manager.requestSerializer=[AFJSONRequestSerializer new];
manager.responseSerializer=[AFJSONResponseSerializer new];
AFSecurityPolicy*policy=[AFSecurityPolicyWithPinningMode:AFSSLPiningModeCertificate];
[策略设置AllowInvalidCertificates:是];
[策略集验证域名:否];
policy.pinnedCertificates=[NSSet setWithObject:certData];
manager.securityPolicy=策略;
[管理员帖子:url参数:无标题:无进度:无成功:^(NSURLSessionDataTask*\u非空任务,id\u可空响应对象){
NSLog(“成功”);
}失败:^(NSURLSessionDataTask*_可空任务,NSError*_非空错误){
NSLog(@“故障:%@”,错误。本地化描述);
}];
每次尝试执行此代码时,都会出现以下错误:

Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “api.example.net” which could put your confidential information at risk."
我尝试对证书(.der、.cer,…)使用不同的格式,但始终会出现相同的错误

我尝试在我的info.plist中使用
NSAllowsArbitraryLoads
,但没有任何变化

为了确保我使用的是工作代码,我还从下载了示例项目,但我自己的证书仍然无效(在教程中,他们使用stackexchange证书,这一个有效)

我已经研究这个问题好几天了,还没有找到解决办法

同样的证书在我们的安卓应用程序和邮递员上都能完美运行

这是因为我使用自签名证书,而iOS不喜欢它吗? 我的代码或应用程序配置中是否有明显遗漏的内容? 是否有特定的东西来实现服务器端,以确保它与iOS一起工作? 我是否必须以非常特定的格式导出我的证书

欢迎提供任何信息


谢谢

我正在看一个旧项目,在那里我使用了自签名证书,没有问题。这些只是可能有帮助的评论——我在这里发表这些评论是因为我有更多的空间,可以更好地格式化它们

der
版本工作正常

Info.plist
中,您需要以下内容

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>server1.local</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
            <key>server2.local</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
            <key>server3.local</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>

此处
fhWebSupportDelegate.serverCertificates
返回一个包含CA和服务器证书的数组。此外,从代码中可以看出,我在授予服务器信任时非常宽容。

非常感谢!我会调查一下,看看是否能成功
// Look to see if we can handle the challenge
- ( void ) URLSession:( NSURLSession                 * ) session
  didReceiveChallenge:( NSURLAuthenticationChallenge * ) challenge
    completionHandler:( void ( ^ ) ( NSURLSessionAuthChallengeDisposition, NSURLCredential * ) ) completionHandler
{
#ifdef DEBUG
    NSLog( @"didReceiveChallenge %@ %zd", challenge.protectionSpace.authenticationMethod, ( ssize_t ) challenge.previousFailureCount );
#endif
    NSURLCredential      * credential = nil;
    NSURLProtectionSpace * protectionSpace;
    SecTrustRef            trust;
    int                    err;

    // Setup
    protectionSpace = challenge.protectionSpace;
    trust = protectionSpace.serverTrust;
    credential = [NSURLCredential credentialForTrust:trust];

    if ( protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust )
    {
        // Build up the trust anchor using server certificates
        err = SecTrustSetAnchorCertificates ( trust, ( CFArrayRef ) fhWebSupportDelegate.serverCertificates );
        SecTrustResultType trustResult = 0;

        if ( err == noErr )
        {
            SecTrustSetAnchorCertificatesOnly ( trust, true );
            err = SecTrustEvaluate ( trust, & trustResult );
#ifdef DEBUG
            NSLog ( @"Trust result %lu", ( unsigned long ) trustResult );
#endif
        }

        BOOL trusted =
        ( err == noErr ) &&
        ( ( trustResult == kSecTrustResultProceed ) || ( trustResult == kSecTrustResultUnspecified ) || ( trustResult == kSecTrustResultRecoverableTrustFailure ) );


        // Return based on whether we decided to trust or not
        if ( trusted )
        {
#ifdef DEBUG
            NSLog ( @"Trust evaluation succeeded" );
#endif
            if ( completionHandler )
            {
                completionHandler ( NSURLSessionAuthChallengeUseCredential, credential );
            }
        }
        else
        {
#ifdef DEBUG
            NSLog ( @"Trust evaluation failed" );
#endif
            if ( completionHandler )
            {
                completionHandler ( NSURLSessionAuthChallengeCancelAuthenticationChallenge, credential );
            }
        }
    }
    else if ( completionHandler )
    {
        completionHandler ( NSURLSessionAuthChallengePerformDefaultHandling, nil );
    }
}