我有以下简单的代码连接到SSL网页

NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:url];
[ NSURLConnection sendSynchronousRequest: urlRequest returningResponse: nil error: &error ];

除非它给出一个错误,如果证书是自签名的一个错误域=NSURLErrorDomain Code=-1202 UserInfo=0xd29930“不受信任的服务器证书”。有没有一种方法来设置它接受连接(就像在浏览器中你可以按accept)或一种方法来绕过它?


当前回答

如果您不愿意(或不能)使用私有api,可以使用一个名为ASIHTTPRequest的开源(BSD许可)库,该库提供了底层CFNetwork api的包装器。他们最近通过- setvalidatessecureccertificate: API引入了允许使用自签名或不受信任证书的HTTPS连接的功能。如果不想提取整个库,可以使用源代码作为自己实现相同功能的参考。

其他回答

这不是我的功劳,但我发现这个真的很适合我的需要。shouldAllowSelfSignedCert是我的BOOL变量。只需添加到你的NSURLConnection委托,你应该是rockin快速绕过每个连接的基础上。

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space {
     if([[space authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
          if(shouldAllowSelfSignedCert) {
               return YES; // Self-signed cert will be accepted
          } else {
               return NO;  // Self-signed cert will be rejected
          }
          // Note: it doesn't seem to matter what you return for a proper SSL cert
          //       only self-signed certs
     }
     // If no other authentication is required, return NO for everything else
     // Otherwise maybe YES for NSURLAuthenticationMethodDefault and etc.
     return NO;
}

在iOS 9中,对于所有无效或自签名的证书,SSL连接将失败。这是iOS 9.0或更高版本、OS X 10.11及更高版本中新的应用程序传输安全特性的默认行为。

您可以在“信息”中覆盖此行为。通过在NSAppTransportSecurity字典中将NSAllowsArbitraryLoads设置为YES。但是,我建议仅为测试目的重写此设置。

有关信息,请参阅这里的应用程序传输技术说明。

有一个支持的API来完成这个!在你的NSURLConnection委托中添加如下内容:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
  return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
  if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    if ([trustedHosts containsObject:challenge.protectionSpace.host])
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

  [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

注意connection:didReceiveAuthenticationChallenge:可以将其消息发送给challenge。发送方(很久以后),在必要时向用户呈现对话框之后,等等。

如果您不愿意(或不能)使用私有api,可以使用一个名为ASIHTTPRequest的开源(BSD许可)库,该库提供了底层CFNetwork api的包装器。他们最近通过- setvalidatessecureccertificate: API引入了允许使用自签名或不受信任证书的HTTPS连接的功能。如果不想提取整个库,可以使用源代码作为自己实现相同功能的参考。

NSURLRequest有一个叫做setAllowsAnyHTTPSCertificate:forHost:的私有方法,它会做你想做的事情。你可以通过一个类别在NSURLRequest上定义allowsAnyHTTPSCertificateForHost:方法,并设置它为你想要覆盖的主机返回YES。