如何使用 Ionic Cordova 框架和自签名证书绕过 iOS 11 中的 SSL 检查

Posted

技术标签:

【中文标题】如何使用 Ionic Cordova 框架和自签名证书绕过 iOS 11 中的 SSL 检查【英文标题】:How to Bypass SSL check in iOS 11 using Ionic Cordova framework and self signed certificate 【发布时间】:2017-10-16 19:30:47 【问题描述】:

在我的应用程序中,我需要调用一些 REST API 服务调用。部署 REST API 服务的目标开发服务器上的证书是自签名的。因此,当我运行应用程序时,我收到如下错误:

加载资源失败:此服务器的证书无效。您可能正在连接到假装“192.168.10.20:8080”无效的服务器......这可能会使您的机密信息面临风险。

由于此服务器仅用于开发/测试目的,所以我只想忽略 ssl 检查...我该如何实现?我尝试了以下方式: [AppDelegate.m 文件] 但没有成功,因为下面的代码在 ios 11 中不起作用...

@implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host

    return YES;

@end

我在我的应用中使用 ionic 3 和 Cordova 7。

【问题讨论】:

不幸的是,“allowsAnyHTTPSCertificateForHost”在 iOS 11 中不再适用于 cordova (WKWebView)。 【参考方案1】:

感谢@peter,我找到了另一种解决方法,用于在 ios11 中检查应用程序,以测试 API 是否正确命中。您可以通过在 config.xml 中添加以下标签来强制将 webview 从 WKWebView 更改为 UIWebview

<preference name="CordovaWebViewEngine" value="CDVUIWebViewEngine" />

现在在 Appdelegate.m 文件中添加以下代码

@implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host

    return YES;

@end

它对我有用..!

注意:仅用于开发/测试目的。不推荐用于生产部署

【讨论】:

这个变通办法的问题是你在使用有点过时的 iOS 网页视图。苹果推荐使用 WKWebView:developer.apple.com/documentation/webkit/wkwebview。这有很多原因(例如,您有触摸延迟,这确实是糟糕的用户体验)。问题是您是否可以让您的用户负担得起?【参考方案2】:

有趣的是,我只是在研究同样的问题。看起来在 iOS 11 中,事情受到了更多限制。我在这里为 WKWebView 回答。

本质上你需要做的:

将自定义身份验证代码放入 WKWebView 插件代码 直接从 Cordova 加载资源(然后正确触发 WKWebView 事件) 禁用 ATS (NSAppTransportSecurity)

详细说明

你应该做的细节如下(如果你使用的是WKWebView):

您需要修改CDVWKWebViewEngine.m(插件代码)。您需要在此处添加:

- (void)webView:(WKWebView *)webView
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge 
*)challenge completionHandler:(void (^)
(NSURLSessionAuthChallengeDisposition 
disposition, NSURLCredential *credential))completionHandler 
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    completionHandler(NSURLSessionAuthChallengeUseCredential, 
    [NSURLCredential credentialForTrust:serverTrust]);

但是,请注意 - 这仅在 WKWebView 初始化时有效(即通过 cordova 框架加载)。

所以您还需要从 API 所在的 URI 加载您的应用程序。我想你有本地网络(自签名证书),所以这应该不是问题。如果您将在本地加载应用程序(即从 index.html),那么这将不起作用!

此外,您需要在应用程序 *.plist 设置文件中禁用 iOS ATS,例如:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

这对我有用。

其他资源:

非常适合不同 SSL 场景(包括自签名)的测试站点:https://badssl.com/ 苹果论坛讨论这个话题:https://forums.developer.apple.com/message/269452#269452

免责声明:应避免禁用证书检查,仅当您有充分的理由或其他限制时才使用此功能。你仍然有通信安全,但你没有信任。因此,中间人攻击是可能的!如果您决定使用此选项,您还应该使用证书固定来使事情更安全。

【讨论】:

@Peter..你能和我分享完整的 CDVWKWebViewEngine.m 文件吗..我已经将这段代码集成到我的中,但没有成功.. @KamleshKumar:我当然可以分享,这里是:gist.github.com/PeterStegnar/63cb8c9a39a13265c3a855e24a33ca37 @PeterStegnar didReceiveAuthenticationChallenge 方法在我的 ionic 4 应用程序中没有被调用 仅在视图初始化时调用。那么你第一次使用或重定向/重新加载它。 @r1webs:按照 Apple 的限制,是的。但是,我强烈建议您不要将其投入生产。这应该仅用于测试目的。【参考方案3】:

我最近遇到了与服务器上的无效 SSL 证书相关的问题。

在我的应用程序中,我正在使用 WKWebView 插件,这已成为将应用程序发送到 App Store 的要求。正是在这个插件中,需要进行调整以忽略无效的 SSL 证书,在文件“plugins/cordova-plugin-ionic-webview/src/ios/CDVWKWebViewEngine.m”中,包括:

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler 

    NSLog(@"Allow all");

    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    CFDataRef exceptions = SecTrustCopyExceptions (serverTrust);

    SecTrustSetExceptions (serverTrust, exceptions);
    CFRelease (exceptions);
    completionHandler (NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);



因此,应用程序不会考虑无效的 SSL 证书。

https://developer.apple.com/forums/thread/15610的引用

请记住,不建议在生产应用程序中执行此操作,因为无效的 SSL 证书会危及应用程序的安全性。

【讨论】:

以上是关于如何使用 Ionic Cordova 框架和自签名证书绕过 iOS 11 中的 SSL 检查的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ngCordova s​​qlite 服务和 Cordova-SQLitePlugin 与 Ionic 框架一起使用?

Cordova + Ionic 框架 - 如何安全地更改包名称?

Cordova/Ionic 应用程序通过服务器签名的 url 将 base64 图像上传到 S3

ionic 和cordova的区别是啥

Cordova笔记三:ionic+angular+cordova技术栈

如何在 Ionic 移动应用程序中为 $cordova 本地通知的本地图像设置图标?