ios https访问自建证书时遇到的问题

本文介绍了一种在iOS应用中使用自签名证书进行HTTPS验证的方法。通过将证书添加到NSBundle资源中,并利用Objective-C代码对服务器信任进行评估,实现对特定自签名证书的信任。文章还讨论了解决.cer文件格式问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上找到方法把证书加到bundle reosource里面:


然后使用下面的代码验证证书:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {

    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{

//     直接验证服务器是否被认证(serverTrust),这种方式直接忽略证书验证,直接建立连接,但不能过滤其它URL连接,可以理解为一种折衷的处理方式,实际上并不安全,因此不推荐。
//     SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
//     return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]
//     forAuthenticationChallenge: challenge];

    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {
        do
            {
            SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
            NSCAssert(serverTrust != nil, @"serverTrust is nil");
            if(nil == serverTrust)
                break; /* failed */
            /**
             *  导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA)
             */
            NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"der"];//自签名证书
            NSData *caCert = [NSData dataWithContentsOfFile:cerPath];

//            NSString *cerPath2 = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"cer"];//SSL证书
//            NSData *caCert2 = [NSData dataWithContentsOfFile:cerPath2];

            if(nil == caCert)
                break; /* failed */

            SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);
            if(nil == caRef)
                break; /* failed */

            NSArray *caArray = @[(__bridge id)(caRef)];
            if(nil == caArray)
                break; /* failed */

            OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
            SecTrustSetAnchorCertificatesOnly(serverTrust,false);
            if(!(errSecSuccess == status))
                break; /* failed */

            SecTrustResultType result = -1;
            status = SecTrustEvaluate(serverTrust, &result);
            if(!(errSecSuccess == status))
                break; /* failed */
            NSLog(@"stutas:%d",(int)status);
            NSLog(@"Result: %d", result);

            BOOL allowConnect = (result == kSecTrustResultUnspecified) || (result == kSecTrustResultProceed);
            if (allowConnect) {
                NSLog(@"success");
            }else {
                NSLog(@"error");
            }

            if(!allowConnect)
                {
                break; /* failed */
                }

#if 0
            /* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success */
            /*   since the user will likely tap-through to see the dancing bunnies */
            if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)
                {
                break; /* failed to trust cert (good in this case) */
                }
#endif

                // The only good exit point
            return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]
                          forAuthenticationChallenge: challenge];
            
            } while(0);
    }
    return [[challenge sender] cancelAuthenticationChallenge: challenge];
}

有个问题就是不能使用.cer的证书,否则SecCertificateCreateWithData会返回nil,我就是被这个坑了两天。。。

原因是:The newly created certificate object. Call the CFRelease function to release this object when you are finished with it. Returns NULL if the data passed in the data parameter is not a valid DER-encoded X.509 certificate.

可以使用:

openssl x509 -in xxx.cer -outform der -out xxx.der来转

这是我参考的文章:http://www.jianshu.com/p/6b9c8bd5005a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值