【问题标题】:android webview with client certificate带有客户端证书的android webview
【发布时间】:2013-03-13 09:39:08
【问题描述】:

我尝试了几天使用嵌入应用程序的客户端证书的 Web 视图,但在我看来,android sdk 没有提供任何方法来做到这一点,是否有回调来拦截由服务器?有没有办法将 webview 与客户端证书一起使用并发出 https 请求?

【问题讨论】:

  • 这个较新的 Q 似乎是重复的,但显示了新的希望:stackoverflow.com/questions/35135225/…
  • 实际上确实有效。我刚刚使用作为证书的 base64 字符串对其进行了测试,立即 ping 我的服务器并正确显示了页面。保留上面的链接并评论说它适用于未来的旅行者!

标签: android ssl webview client certificate


【解决方案1】:

由于我也对您的问题感兴趣,因此我检查了 WebView 和 WebViewClient 的文档,四处浏览,确实看起来您无法使用客户端证书对 webview 会话进行身份验证,这是所需的方法 (ClientCertRequestHandler)不是公共 API。

Using a Android WebView to connect to secure server with Client Certificate

在 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。团队可能会在未通知的情况下修改/删除该方法,并且您的应用可能会停止在 SO 的未来版本上运行。

解决方案 2:

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

Load local HTML file into WebView

但我强烈怀疑 webview 会像浏览器一样运行......

解决方案 3:(应该可行,但需要付出很多努力)

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

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

你有我的同情。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果您只需要忽略 Web 视图中的 ssl 证书请求,这在 Lollipop 上对我有用:

      在您的 Web 视图客户端中,覆盖:

      @Override
      public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
          handler.proceed(); // Ignore SSL certificate errors
      }
      

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

      【讨论】:

      • #refreshing。使用这个 sn-p 代码,您的应用很有可能在谷歌应用验证中被拒绝。它发生在我身上。请参阅stackoverflow.com/questions/35720753/…
      • 这不是“被拒绝的巨大机会”,Play 商店会自动检测到这种绕过并毫无机会地拒绝 :)
      • 我的应用昨天因为这个代码被拒绝了。我不会再用这个了。
      • @Nickmccomb 请仔细阅读答案!正如它所说,“这对于针对 qa/dev/stage 环境调试 webview 很有用。”不适用于生产代码。
      【解决方案4】:

      为了根据更新的安全政策正确处理 SSL 证书验证以防止应用程序被 Google play 拒绝,更改您的代码以在服务器提供的证书符合您的期望时调用 SslErrorHandler.proceed(),并调用 SslErrorHandler.cancel( ) 否则。

      例如,我添加了一个警告对话框以使用户确认并且似乎 Google 不再显示警告。

          @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();
      }
      

      更改后不会显示警告。

      【讨论】:

        【解决方案5】:

        Android 4.4 上基于 Chronium 的 WebView 引入了一个错误:当服务器请求客户端证书时,WebView 停止加载过程。 onPageFinished-方法会立即被调用,但不显示页面。

        --> https://code.google.com/p/android/issues/detail?id=62533

        【讨论】:

          【解决方案6】:

          我们无法在 webview 中访问客户端证书, 有一个谷歌问题同样提出。 https://code.google.com/p/android/issues/detail?id=53491

          【讨论】:

            【解决方案7】:

            onReceivedClientCertRequest() 自 API 21 起被添加到 WebViewClient。 https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)

            以下 Stackoverflow 帖子中的解决方案对我有用: Android WebView handle onReceivedClientCertRequest

            测试:

            当客户端证书没有设置时,你会看到“400 bad request”。

            【讨论】:

              【解决方案8】:

              自签名 SSL 证书对我有用

              请查看此答案https://stackoverflow.com/a/49003522/5058630

              【讨论】:

                猜你喜欢
                • 2014-01-11
                • 1970-01-01
                • 1970-01-01
                • 2017-01-24
                • 2011-12-10
                • 2013-02-25
                • 2023-03-23
                • 1970-01-01
                • 2012-03-21
                相关资源
                最近更新 更多