首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用CA和客户端证书自定义RestTemplate,而不将crts导入jvm

使用CA和客户端证书自定义RestTemplate,而不将crts导入jvm
EN

Stack Overflow用户
提问于 2022-08-08 18:43:12
回答 1查看 90关注 0票数 0

我有一个带有自定义RestTemplate的Spring应用程序,它从文件(从资源文件夹)加载客户端证书。

现在我如何也可以从文件中向这个RestTemplate添加CA证书(PEM文件)?(或者用spring引导实现目标的其他方法?)

代码语言:javascript
运行
复制
@Bean public RestTemplate restTemplate() ... {

  SSLContext sslContext = new SSLContextBuilder()
          .loadTrustMaterial(new URL(clientCert), str.toCharArray()).build();
  SSLConnectionSocketFactory sslConFactory = new SSLConnectionSocketFactory(sslContext);
  CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConFactory).build();
  ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
  return new RestTemplate(requestFactory);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-10 22:02:16

不久前,我遇到了一些在用例中可能有帮助的代码。

它可以在这个储存库获得麻省理工学院的许可。

重要工件是在这个包裹中定义的。

基本上,库提出了一个名为SSLContextFactory的助手类。

这个类定义了一个方法,用于创建一个带有客户端证书的SSLContext、它的密码和相应的CA证书,最后一个证书是从一个名为makeContext的证书文件中复制的,为了方便起见:

代码语言:javascript
运行
复制
public SSLContext makeContext(File clientCertFile, String clientCertPassword, String caCertString) throws Exception {
  final KeyStore keyStore = loadPKCS12KeyStore(clientCertFile, clientCertPassword);
  KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
  kmf.init(keyStore, clientCertPassword.toCharArray());
  KeyManager[] keyManagers = kmf.getKeyManagers();


  final KeyStore trustStore = loadPEMTrustStore(caCertString);
  TrustManager[] trustManagers = {new CustomTrustManager(trustStore)};


  SSLContext sslContext = SSLContext.getInstance("TLS");
  sslContext.init(keyManagers, trustManagers, null);


  return sslContext;
}

如您所见,它使用不同的帮助方法和助手类CustomTrustManager

请注意,这个解决方案已经相当过时了,但我认为它仍然是合适的。

然后,在构造makeContext时使用RestTemplate方法

代码语言:javascript
运行
复制
@Bean public RestTemplate restTemplate() {
    SSLContextFactory sslContextFactory = SSLContextFactory.getInstance();
    SSLContext sslContext = sslContextFactory.makeContext(clientCert, str.toCharArray(), caCertPem);
    SSLConnectionSocketFactory sslConFactory = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConFactory).build();
    ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
    return new RestTemplate(requestFactory);
}

如果您的PEM文件包含证书链,则可以通过以下内容修改在loadPEMTrustStore中定义的SSLContextFactory方法:

代码语言:javascript
运行
复制
private KeyStore loadPEMTrustStore(String certificateString) throws Exception {
  try (InputStream certificateStream = certificateString.getBytes()) {
    CertificateFactory certificateFactory = 
      CertificateFactory.getInstance("X.509");
    // note the change in the method, we use generateCertificates
    Collection<X509Certificate> certificates = 
      (Collection<X509Certificate>) 
      certificateFactory.generateCertificates(certificateStream);
  
    KeyStore trustStore = 
      KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(null);

    String alias;
    for (X509Certificate certificate : certificates) {
      alias = certificate.getSubjectX500Principal().getName();
      trustStore.setCertificateEntry(alias, certificate);
    }

    return trustStore;
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73282644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档