当前位置: 首页 > 知识库问答 >
问题:

在Android中重写SSL信任管理器

胡飞舟
2023-03-14

我正在尝试覆盖Android中的信任管理器。我想让基础信任管理器检查证书,但我需要确定证书是否过期。如果证书过期,我需要忽略它并接受证书。如果电池被移除,一些移动设备会将日期重置为旧日期,导致证书看起来好像过期了。我的应用程序必须继续保持运行,即使发生这种情况。

我遇到的问题是这行代码抛出了NullPointerException:

origTrustmanager.checkServerTrusted(certs, authType);
class SSLTrustManager
{
  private X509TrustManager origTrustmanager;

  public SSLTrustManager()
  {
    try
    {
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      tmf.init((KeyStore) null);
      TrustManager[] trustManagers = tmf.getTrustManagers();
      this.origTrustmanager = (X509TrustManager) trustManagers[0];
    }
    catch (Exception ex)
    {
    }
  }

  public javax.net.ssl.SSLSocketFactory GetSocketFactory()
  {
    try
    {
      TrustManager[] wrappedTrustManagers = new TrustManager[] {
          new X509TrustManager()
          {
            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
              return origTrustmanager.getAcceptedIssuers();
            }

            public void checkClientTrusted(X509Certificate[] certs, String authType)
            {
              try
              {
                origTrustmanager.checkClientTrusted(certs, authType);
              }
              catch (CertificateException e)
              {
              }
            }

            public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException
            {
              try
              {
                origTrustmanager.checkServerTrusted(certs, authType);
              }
              catch(Exception ex)
              {
              }
            }
          }
       };

      SSLContext sslContext = SSLContext.getInstance("SSL");
      sslContext.init(null, wrappedTrustManagers, new java.security.SecureRandom());
      javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
      return sslSocketFactory;
    }
    catch (Exception ex)
    {
      return null;
    }
  }
}    

访问URL的代码:

SSLTrustManager sslTrustManager = new SSLTrustManager();
HttpsURLConnection.setDefaultSSLSocketFactory(sslTrustManager.GetSocketFactory());

URL siteUrl = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) siteUrl.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);

DataOutputStream out = new DataOutputStream(conn.getOutputStream());

共有1个答案

凌展
2023-03-14

如果您从未初始化origTrustManager实例变量,它的默认值将为null,这确实会在您尝试使用它时导致NPE。

我刚刚编辑了前面关于这个问题的答案,以显示一个TrustManager初始化的示例。(我还没有在Android上试过,但它在普通Java上运行得很好。)

小心别抓太多。在这里,您将在信任管理器中捕获CertificateExceptionException:这与什么都没有一样好,因为这些方法是用来抛出这些异常的。如果要忽略过期日期,请确保只捕获CertificateExpireDexception

注意,这只是一个依赖于这样一个事实的把戏:在实践中,证书验证是在一般信任验证之后完成的(至少在OpenJDK实现中是这样)。据我所知,规范中没有说明证书过期是在之后进行验证的。它是在对信任元素进行其他验证之前完成的,并且您忽略了该异常,您可以让更多的证书通过,而不是您想要的。

 类似资料:
  • Key Management Content trust is directly associated with an image tag and each repository has a set of keys that publishers use to sign each image. A repository can have both unsigned and signed image

  • 我是flink的新手,我部署了我的flink应用程序,它基本上执行简单的模式匹配。它部署在库伯内特斯集群中,具有1个JM和6个TM。我每10分钟向eventhub主题发送大小4.4k和200k消息并执行负载测试。我添加了重启策略和检查点,如下所示,我没有在代码中显式使用任何状态,因为没有要求 最初,我遇到了网络缓冲区的Netty服务器问题,我遵循了以下链接https://ci.apache.org

  • 我最近在我的Windows8电脑上安装了Android studio。现在,当我尝试访问AVD管理器或SDK管理器时,会收到类似“请指定Android SDK”的错误消息。。解决这个问题的办法是什么?在Android studio中是否也有类似eclipse的“关闭项目”选项?

  • 当我尝试使用Android SDK管理器下载适用于Android 4.1的ARM EABI时,它拒绝安装。我收到以下消息:“SSL对等点错误关闭”。这是在Windows XP操作系统上。你知道这里发生了什么,我能做些什么来解决这个问题吗?

  • 每个新创建的任务都是 org.gradle.api.DefaultTask 类型, org.gradle.api.Task 的标准实现,DefaultTask 所有的域都是私有的,意味着他们只能通过 setter 和 getter 方法来访问,庆幸的是Groovy提供了一些语法糖来允许你通过名字来使用域。 管理项目的版本 许多公司或者开源组织有他们自己的发布版本的措施,一般用主版本号和次版本号来表

  • 用 ceph-deploy 建立一个集群后,你可以把客户端管理密钥和 Ceph 配置文件发给其他管理员,以便让他用 ceph 命令管理集群。 创建一管理主机 要允许一主机以管理员权限执行 Ceph 命令,用 admin 命令: ceph-deploy admin {host-name [host-name]...} 分发配置文件 要把改过的配置文件分发给集群内各主机,可用 config push