Android WebView使用客户端证书

22

我尝试使用内嵌在应用中的客户端证书来使用Web视图,但好像安卓SDK并没有提供任何方法来做到这一点,是否有回调函数可以拦截服务器发送的挑战?是否有办法使用带有客户端证书并进行 HTTPS 请求的 Web 视图?


这个比较新的 Q 看起来是一个重复,但展现了新的希望:https://dev59.com/RVsW5IYBdhLWcg3wTly8 - Stephen J
实际上,这确实有效。我刚刚使用一个base64字符串进行了测试,它是一个证书,立即ping了我的服务器并正确地显示了页面。保留上面的链接和评论,以便未来的旅行者! - Stephen J
8个回答

54

由于我对你的问题也感兴趣,我查阅了WebView和WebViewClient的文档,并进行了搜索,确实看起来你无法使用客户端证书对webview会话进行身份验证,因为所需的方法(ClientCertRequestHandler)不是公共API。

在安卓WebView中使用客户端证书连接到安全服务器

在Android安全讨论中进行搜索确认该调用确实不可用:

https://groups.google.com/forum/#!msg/android-security-discuss/0hzTGaA9swQ/1Oqc8UpGLH8J

尽管

Android 4.0版本确实包括浏览器中对客户端证书的认证支持。

(参考:https://code.google.com/p/android/issues/detail?id=8196)

但没有提及WebViews :(

即使有一些新的API可以加载钥匙串中的证书:

http://developer.android.com/reference/android/security/KeyChain.html http://nelenkov.blogspot.it/2011/11/using-ics-keychain-api.html

仍然不清楚WebView是否会使用它们...因此,我想你应该尝试KeyChain类,并查看是否可以正确验证(我没有简单的方法来测试这一点,所以你需要自己尝试)。

如果KeyChain不能与WebViews一起工作,那么我想这归结为几个远非完美的解决方法:

解决方案 1:

仍然使用ClientCertRequestHandler(虽然被标记为隐藏,但显然仍可用):

https://code.google.com/p/android/issues/detail?id=53491

然而,即使您做到了这一点,Android Dev. Team也可能在未经通知的情况下修改/删除该方法,您的应用可能无法在未来的SO版本上工作。

解决方案 2:

如果您可以将目标限制在Android 4.0或更高版本,则一个大胆(且不太可能...)的解决方案是尝试使用文件方案从本地存储加载Webview中的证书:

将本地HTML文件加载到WebView中

但我强烈怀疑Webview将像浏览器那样运行...

解决方案 3:(应该有效,但需要大量努力)

使用HTTPClient或HttpURLConnection在后台处理每个https连接,然后将数据传递给WebView:

http://chariotsolutions.com/blog/post/https-with-client-certificates-on/

您有我的同情。


9
在 API 21(Android Lollipop)及更高版本中,您可以覆盖 WebViewClient.onReceivedClientCertRequest(WebView view, ClientCertRequest request) 方法。在该方法中,使用您的密钥管理器获取私钥和证书链,并调用 request.proceed()

9
如果您只需要在Web视图中忽略ssl证书请求,这对我在Lollipop上有效:
在您的Web视图客户端内,覆盖:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    handler.proceed(); // Ignore SSL certificate errors
}

这对于针对qa/dev/stage环境调试webview非常有用。


1
使用这段代码片段,您的应用程序很有可能在Google应用验证中被拒绝。我曾经遇到过这种情况。请参见https://dev59.com/kVsV5IYBdhLWcg3w2h0s - Franklin Hirata
3
这并不是“被拒的很大机会”,Play商店会自动检测到这种绕过方式,并且毫无机会地拒绝 :) - StevenTB
1
我的应用程序昨天因为这段代码被拒绝了。我不会再使用它了。 - Nickmccomb
3
@Nickmccomb请仔细阅读答案!正如它所述,“这对于针对qa/dev/stage环境调试webviews非常有用。”不适用于生产代码。 - Eduard

8
为了遵守更新的安全策略,以防止应用程序被谷歌商店拒绝,请正确处理SSL证书验证。当服务器呈现的证书符合您的期望时,请更改您的代码以调用SslErrorHandler.proceed(),否则请调用SslErrorHandler.cancel()。
例如,我添加了一个警报对话框,让用户确认后,似乎谷歌不再显示警告。
    @Override
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    String message = "SSL Certificate error.";
        switch (error.getPrimaryError()) {
            case SslError.SSL_UNTRUSTED:
                message = "The certificate authority is not trusted.";
                break;
            case SslError.SSL_EXPIRED:
                message = "The certificate has expired.";
                break;
            case SslError.SSL_IDMISMATCH:
                message = "The certificate Hostname mismatch.";
                break;
            case SslError.SSL_NOTYETVALID:
                message = "The certificate is not yet valid.";
                break;
        }
        message += " Do you want to continue anyway?";

        builder.setTitle("SSL Certificate Error");
        builder.setMessage(message);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}

经过这些更改后,它将不会显示警告。


3

0

0

自API 21以来,已将onReceivedClientCertRequest()添加到WebViewClient中。 https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)

以下Stackoverflow帖子中的解决方案对我有效: Android WebView处理 onReceivedClientCertRequest

进行测试:

当未设置客户端证书时,将显示“400 bad request”。


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接