Xamarin WKWebView 接受自签名证书

Xamarin WKWebView Accepting Self-Signed Certificates

我在网上看到了各种说明如何接受它们的示例,但我总是得到 发生 SSL 错误并且无法与服务器建立安全连接。

我会注意到肯定会调用该方法(运行 在 iOS 8.4 模拟器和 iOS 11 实际设备上),因此未调用的方法不是这里的问题。

到目前为止我尝试了什么(显然我只在开发中使用这段代码而不在生产中使用,等等等等):

1:

public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) {
 completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, new NSUrlCredential(serverTrust));
}

2:

public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) {
 completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(serverTrust));
}

3:

    public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) {
        SecTrust serverTrust = challenge.ProtectionSpace.ServerSecTrust;
        NSData exceptions = serverTrust.GetExceptions();
        serverTrust.SetExceptions(exceptions);
        exceptions.Dispose();
        completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(serverTrust));
    }

4:

    public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) {
        SecTrust serverTrust = challenge.ProtectionSpace.ServerSecTrust;    //TODO: Get the following working (currently we still receive SSL errors)
        NSData exceptions = serverTrust.GetExceptions();
        serverTrust.SetExceptions(exceptions);
        exceptions.Dispose();

        challenge.Sender.UseCredential(NSUrlCredential.FromTrust(serverTrust), challenge);
        completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(serverTrust));
    }

我做错了什么?谢谢

要支持自签名证书,您两个事情要做:

  1. 在您的自签名域上允许 NSExceptionAllowsInsecureHTTPLoads
    • 即使您使用的是 https,您的应用也被标记为存在信任问题
  2. 绕过证书安全检查

关于 2 的安全说明:为任何生产应用程序获取 CA 颁发的证书,因为这会完全禁用对您的域的证书验证,从而允许 MITM 攻击、您的 DNS 重定向欺骗应用程序等...您可以通过在主包中包含 public cer 并根据收到的证书检查它来固定证书,但这仅意味着需要在 MITM 或 DNS 中生成假证书欺骗攻击(以及各种漏洞利用工具包中已经存在的工具)

使用 https://badssl.com 站点的示例:

WKNavigationDelegate:

public class NavigationDelegate : WKNavigationDelegate
{
    const string host = "self-signed.badssl.com";
    public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
    {
        switch (challenge.ProtectionSpace.Host)
        {
            case host:
                using (var cred = NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust))
                {
                    completionHandler.Invoke(NSUrlSessionAuthChallengeDisposition.UseCredential, cred);
                }
                break;
            default:
                completionHandler.Invoke(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, null);
                break;
        }
    }
}

注意:将此 class 的实例分配给 WKWebView 实例的 NavigationDelegateWeakNavigationDelegate

Info.plist NSAppTransportSecurity:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>self-signed.badssl.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>