我可以在不重新启动 JVM 的情况下将新证书添加到密钥库吗?

发布于 2024-09-27 16:28:45 字数 80 浏览 2 评论 0原文

我想将新证书导入密钥库,而无需重新启动正在运行的服务。这可能吗?

或者,是否可以指定要使用的证书不在特定 URL 连接的密钥库中?

I'd like to import a new certificate into the keystore without restarting a running service. Is that possible?

Alternatively, is it possible to specify a certificate to use that's not in the keystore for a specific URL connection?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里人 2024-10-04 16:28:45

事实证明,您可以指定用于特定 URL 获取的特定证书;本质上,您需要创建自己的 TrustManager 并将其交换,如下所示:

public String fetchFromUrl(String urlString) throws IOException {
  URL url = new URL(urlString);
  URLConnection conn = url.openConnection();

  if (conn instanceof HttpsURLConnection && shouldSubstituteCert(url)) {
    HttpsURLConnection sslConn = (HttpsURLConnection) conn;
    try {
      SSLContext context = SSLContext.getInstance("SSL");
      context.init(null, new TrustManager[] {new MyTrustManager()}, null);
      sslConn.setSSLSocketFactory(context.getSocketFactory());
    } catch (Exception e) {
      e.printStackTrace();
      throw new IOException("Error creating custom keystore", e);
    }
  }

  return readAll(conn.getInputStream());
}

private static class MyTrustManager implements X509TrustManager {
  private final X509TrustManager trustManager;
  public MyTrustManager() throws 
      KeyStoreException, NoSuchAlgorithmException, 
      CertificateException, IOException {

    // Load a KeyStore with only our certificate
    KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
    store.load(null, null);
    Certificate cert = loadPemCert();
    store.setCertificateEntry("me.com", cert);

    // create a TrustManager using our KeyStore
    TrustManagerFactory factory = TrustManagerFactory.getInstance(
        TrustManagerFactory.getDefaultAlgorithm());
    factory.init(store);
    this.trustManager = getX509TrustManager(factory.getTrustManagers());
  }

  public void checkClientTrusted(X509Certificate[] chain, String authType)
      throws CertificateException {
    trustManager.checkClientTrusted(chain, authType);
  }

  public void checkServerTrusted(X509Certificate[] chain, String authType)
      throws CertificateException {
    trustManager.checkServerTrusted(chain, authType);
  }

  public X509Certificate[] getAcceptedIssuers() {
    return trustManager.getAcceptedIssuers();
  }

  private static X509TrustManager getX509TrustManager(TrustManager[] managers) {
    for (TrustManager tm : managers) {
      if (tm instanceof X509TrustManager) {
        return (X509TrustManager) tm;
      }
    }
    return null;
  }

  private Certificate loadPemCert() 
      throws CertificateException, IOException {
    InputStream stream = 
      this.getClass().getClassLoader().getResourceAsStream("cert.pem");

    CertificateFactory factory = CertificateFactory.getInstance("X.509");
    return factory.generateCertificate(stream);
  }
}

Turns out you can specify specific certificates to use for specific URL fetches; essentially, you need to create your own TrustManager and swap it in, like so:

public String fetchFromUrl(String urlString) throws IOException {
  URL url = new URL(urlString);
  URLConnection conn = url.openConnection();

  if (conn instanceof HttpsURLConnection && shouldSubstituteCert(url)) {
    HttpsURLConnection sslConn = (HttpsURLConnection) conn;
    try {
      SSLContext context = SSLContext.getInstance("SSL");
      context.init(null, new TrustManager[] {new MyTrustManager()}, null);
      sslConn.setSSLSocketFactory(context.getSocketFactory());
    } catch (Exception e) {
      e.printStackTrace();
      throw new IOException("Error creating custom keystore", e);
    }
  }

  return readAll(conn.getInputStream());
}

private static class MyTrustManager implements X509TrustManager {
  private final X509TrustManager trustManager;
  public MyTrustManager() throws 
      KeyStoreException, NoSuchAlgorithmException, 
      CertificateException, IOException {

    // Load a KeyStore with only our certificate
    KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
    store.load(null, null);
    Certificate cert = loadPemCert();
    store.setCertificateEntry("me.com", cert);

    // create a TrustManager using our KeyStore
    TrustManagerFactory factory = TrustManagerFactory.getInstance(
        TrustManagerFactory.getDefaultAlgorithm());
    factory.init(store);
    this.trustManager = getX509TrustManager(factory.getTrustManagers());
  }

  public void checkClientTrusted(X509Certificate[] chain, String authType)
      throws CertificateException {
    trustManager.checkClientTrusted(chain, authType);
  }

  public void checkServerTrusted(X509Certificate[] chain, String authType)
      throws CertificateException {
    trustManager.checkServerTrusted(chain, authType);
  }

  public X509Certificate[] getAcceptedIssuers() {
    return trustManager.getAcceptedIssuers();
  }

  private static X509TrustManager getX509TrustManager(TrustManager[] managers) {
    for (TrustManager tm : managers) {
      if (tm instanceof X509TrustManager) {
        return (X509TrustManager) tm;
      }
    }
    return null;
  }

  private Certificate loadPemCert() 
      throws CertificateException, IOException {
    InputStream stream = 
      this.getClass().getClassLoader().getResourceAsStream("cert.pem");

    CertificateFactory factory = CertificateFactory.getInstance("X.509");
    return factory.generateCertificate(stream);
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文