Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/119.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS UIWebView上的客户端证书身份验证适用于iOS 6.1,但不适用于iOS 7_Ios_Ssl_Ios7 - Fatal编程技术网

iOS UIWebView上的客户端证书身份验证适用于iOS 6.1,但不适用于iOS 7

iOS UIWebView上的客户端证书身份验证适用于iOS 6.1,但不适用于iOS 7,ios,ssl,ios7,Ios,Ssl,Ios7,我正在尝试使用客户端证书身份验证来访问安全的网站。我正在使用的代码在iOS 6.1中运行良好,但在使用iOS 7时服务器返回403.7错误,因此失败 我使用connection:willSendRequestForAuthenticationChallenge处理程序检查身份验证方法并提供客户端证书 我的代码是: - (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:

我正在尝试使用客户端证书身份验证来访问安全的网站。我正在使用的代码在iOS 6.1中运行良好,但在使用iOS 7时服务器返回403.7错误,因此失败

我使用connection:willSendRequestForAuthenticationChallenge处理程序检查身份验证方法并提供客户端证书

我的代码是:

- (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        NSLog(@"Trust Challenge");
        SecTrustResultType trustResultType;
        OSStatus err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);

        NSLog(@"SecTrustResult %u %d",trustResultType, (int)err);

        if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultConfirm || trustResultType == kSecTrustResultUnspecified) {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
        }
        else{
            [challenge.sender cancelAuthenticationChallenge:challenge];
        }

    } else {
        NSString *path = [[NSBundle mainBundle]pathForResource:@"mycert" ofType:@"pfx"];
        NSData *p12data = [NSData dataWithContentsOfFile:path];

        CFDataRef inP12data = (__bridge CFDataRef)p12data;

        SecIdentityRef myIdentity;
        SecTrustRef myTrust;
        extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
        assert(myIdentity != nil);
        assert(myTrust != nil);

        long count = SecTrustGetCertificateCount(myTrust);
        NSMutableArray* myCertificates = nil;
        if(count > 1) {
            myCertificates = [NSMutableArray arrayWithCapacity:count];
            for(int i = 1; i < count; ++i) {
                [myCertificates addObject:(__bridge id)SecTrustGetCertificateAtIndex(myTrust, i)];
            }
        }

        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:myCertificates persistence:NSURLCredentialPersistenceNone];
        assert(credential != nil);

        NSLog(@"User: %@, certificates %@ identity:%@", [credential user], [credential certificates], [credential identity]);
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    }
}
mycert.pfx文件包含中间证书和客户端证书

从未调用connection:didFailWithError函数

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        NSLog(@"Error: %@", [error userInfo]);
    }
因此,似乎证书协商在某种程度上成功了

我的问题与类似,但我使用的是带IIS 7.5的Windows Server 2008 R2。已在服务器上启用TLS 1.1和TLS 1.2协议

WireShark跟踪显示,使用iOS 7时,TLS握手期间的证书帧为空。使用iOS 6.1时会发送并验证证书

我可以使用Safari访问iOS 7中的站点


非常感谢您的帮助。

在苹果开发者支持的帮助下,我找到了一个解决方案。解决方案包括创建自定义NSURL协议。我在上使用了Apple示例代码。示例代码显示了如何覆盖HTTPS服务器信任评估,因此需要对其进行修改以使用客户端证书身份验证

我修改了AppDelegate DiReceiveAuthenticationChallenge函数

- (void)customHTTPProtocol:(CustomHTTPProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
// A CustomHTTPProtocol delegate callback, called when the protocol has an authenticate
// challenge that the delegate accepts via -   customHTTPProtocol:canAuthenticateAgainstProtectionSpace:.
// In this specific case it's only called to handle server trust authentication challenges.
// It evaluates the trust based on both the global set of trusted anchors and the list of trusted
// anchors returned by the CredentialsManager.
{
    OSStatus            err;
    NSURLCredential *   credential;

    assert(protocol != nil);
    assert(challenge != nil);

    credential = nil;

    // Handle ServerTrust and Client Certificate challenges

    NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
    if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSLog(@"Trust Challange");
        SecTrustResultType trustResultType;
        err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);

        NSLog(@"SecTrustResult %u %d",trustResultType, (int)err);

        if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultUnspecified) {
            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            assert(credential != nil);
        }
    } else {
        NSString *path = [[NSBundle mainBundle]pathForResource:@"mycert" ofType:@"pfx"];
        NSData *p12data = [NSData dataWithContentsOfFile:path];

        SecIdentityRef identity = NULL;
        SecCertificateRef certificate = NULL;

        [Util identity:&identity andCertificate:&certificate fromPKCS12Data:p12data withPassphrase:@"asia1215"];

        assert(identity != NULL);

        NSArray *certArray = [NSArray arrayWithObject:(__bridge id)certificate];
        credential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
    }

    [protocol resolveAuthenticationChallenge:challenge withCredential:credential];
}
- (void)customHTTPProtocol:(CustomHTTPProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
// A CustomHTTPProtocol delegate callback, called when the protocol has an authenticate
// challenge that the delegate accepts via -   customHTTPProtocol:canAuthenticateAgainstProtectionSpace:.
// In this specific case it's only called to handle server trust authentication challenges.
// It evaluates the trust based on both the global set of trusted anchors and the list of trusted
// anchors returned by the CredentialsManager.
{
    OSStatus            err;
    NSURLCredential *   credential;

    assert(protocol != nil);
    assert(challenge != nil);

    credential = nil;

    // Handle ServerTrust and Client Certificate challenges

    NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
    if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSLog(@"Trust Challange");
        SecTrustResultType trustResultType;
        err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);

        NSLog(@"SecTrustResult %u %d",trustResultType, (int)err);

        if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultUnspecified) {
            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            assert(credential != nil);
        }
    } else {
        NSString *path = [[NSBundle mainBundle]pathForResource:@"mycert" ofType:@"pfx"];
        NSData *p12data = [NSData dataWithContentsOfFile:path];

        SecIdentityRef identity = NULL;
        SecCertificateRef certificate = NULL;

        [Util identity:&identity andCertificate:&certificate fromPKCS12Data:p12data withPassphrase:@"asia1215"];

        assert(identity != NULL);

        NSArray *certArray = [NSArray arrayWithObject:(__bridge id)certificate];
        credential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
    }

    [protocol resolveAuthenticationChallenge:challenge withCredential:credential];
}