Switching from http to https. Invalid certificate

23,503

Solution 1

For getting around the validity check of the host certificate, add the following code.

First add an interface for the setter method that is already within the SDK but not exposed into public:

@interface NSURLRequest(Private)
+(void)setAllowsAnyHTTPSCertificate:(BOOL)inAllow forHost:(NSString *)inHost;
@end

Now, whenever you are rendering a new request, invoke that setter:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[inURL host]];

Warning

Do not use this code for production but only while developing your app in cases where the certificate is not yet approved/submitted/installed. Typical would be the use of a development server that does not have a trusted certificate installed. The use of this code will get your App rejected from distribution via iTunes as it uses a private API method.

For making sure that things work smoothly in a production environment, you will have to get a trusted SSL certificate for your host. There are various authoritative companies providing such thing. To mention at least one (there are MANY more), you could use GoDaddy.


Update (31st May 2013)

AFNetworking got updated to support invalid certificates out of the box, without using any private API's. Kudos to Peter Steinberger!

For enabling that feature, the most convenient solution is to add the following to your prefix header (.pch):

#ifdef DEBUG
#define _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_
#endif

Once again, I can not emphasize enough that you should refrain from enabling that feature in production code - you would pretty much invalidate the entire point of SSL connections and render them vulnerable.

Solution 2

This URL from Apple documentation might help Check this link

In the above document read Introduction section. Screenshot for Apple document

Share:
23,503
Darren
Author by

Darren

Updated on July 09, 2022

Comments

  • Darren
    Darren almost 2 years

    I have an app that connects to my home routers web interface. I want to convert this to use https instead of just http. I was originally using ASIHttpRequest, but as it's no longer supported i'm switching over to AFNetworking. The problem is, whenever I try to connect, I get this error message:

    _block_invoke_0220 [Line 243] ERROR: Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.1.1” which could put your confidential information at risk." UserInfo=0x9792ad0 {NSErrorFailingURLStringKey=https://192.168.1.1/Info.live.htm, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLKey=https://192.168.1.1/Info.live.htm, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.1.1” which could put your confidential information at risk., NSUnderlyingError=0xa6a3560 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.1.1” which could put your confidential information at risk.", NSURLErrorFailingURLPeerTrustErrorKey=< SecTrustRef:
    

    If I navigate to the url i safari, I get a message that Safari can't verify the identity.... and I have to click continue to carry on. How can I achieve this? I don't really know anything about ssl or https unfortunately. Here is the code i'm currently using:

    NSString *urlString = @"https://192.168.1.1/";
    NSURL *url = [NSURL URLWithString:urlString];
    
    // Set authorization
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
    [httpClient setAuthorizationHeaderWithUsername:user password:pass];
    
    NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"Info.live.htm" parameters:nil];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSString *responceString = [operation responseString];
        //        NSLog(@"%@",responceString);
        if ([self parseInfoLive:responceString])
            [[NSNotificationCenter defaultCenter] postNotificationName:@"downloadsComplete" object:nil];
    }
                                     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                         NSLog(@"ERROR: %@",error.description);
                                     }];
    
    
    [operation start];
    
    • mostafa tourad
      mostafa tourad over 11 years
      The certificate obviously is not trusted in conjunction with the host you are submitting. You will have to disable the validity check to get this working - warning do not submit such app to the App Store but only use such solution for your development phase.
    • Darren
      Darren over 11 years
      Thanks. How do I disable the validity check? I've tried adding #define AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES 1 to the top of the code.
    • Darren
      Darren over 11 years
      Also, if you say not to submit the app like that, what would be a solution to make the certificate trusted?
  • Darren
    Darren over 11 years
    Thanks. That works now. I guess i'll have to speak to those that requested this to see if they have valid certificates.
  • Darren
    Darren over 11 years
    Is it possible to add the self-signed certificate to the app that you can accept when you navigate to the url using safari?
  • mostafa tourad
    mostafa tourad over 11 years
    You should refrain from using self-signed certificates in a production environment. Use a properly accepted certificate, it is really not that hard or expensive.
  • Darren
    Darren over 11 years
    The problem is, my app connects to the users servers. So they'd need their own on their server. But the servers do have a self-signed one as default.
  • mostafa tourad
    mostafa tourad over 11 years
    That indeed is a challenge. I do not know how you could circumvent the certificate validation in an iTunes accepted way. Using the code above will get you rejected as it uses a private API method.
  • Jay O'Conor
    Jay O'Conor over 11 years
    An answer that shows the public API to use to handle a self-signed certificate can be found here: I want to ignore certificate verification, where and how to do it with XMLRPC web service?
  • Darren
    Darren over 11 years
    Thanks. That link led me to a few different things to try. 1, Cocoanetics suggests a way to bypass cert checking for a specific domain. 2, GDS blog suggests you can add a self cert certificate to the Trusted certs on a device by emailing it to yourself. I wonder if I can ship it with an app and have it install?
  • mostafa tourad
    mostafa tourad almost 11 years
    @JayO'Conor that certainly is a better way when using NSURLConnection. The question however was referring to the use of AFNetworking and not NSURLConnection.
  • mostafa tourad
    mostafa tourad almost 11 years
    That quoted solution does not use AFNetworking, hence it does not answer the question.
  • Jay O'Conor
    Jay O'Conor almost 11 years
    @Till AFNetworking is built on top of NSURLConnection. AFURLConnectionOperation implements NSURLConnection delegate method -connection:canAuthenticateAgainstProtectionSpace: AFNetworking provides AFURLConnectionOperation -setAuthenticationAgainstProtectionSpaceBlock: which is pretty much just a block wrapper around the NSURLConnection delegate method.
  • Jayprakash Dubey
    Jayprakash Dubey over 9 years
    @Ross : Where to include "interface NSURLRequest" code?
  • Ben Thielker
    Ben Thielker about 8 years
    FYI: Using a GoDaddy cert will unfortunately not resolve this issue, as they are not trusted by iOS. The user would have to open the domain in Safari and trust the certificate there before the connection will work in the app.