immersed-in-the-deep-sea

导航

 

是这样的,大概前一段时间做过一个业务,一直没有记录下来

就是我们的算法部,封装好了一系列的算法,然后是python写的。而我们需要用Java去调用他们的方法。

如何处理这个问题呢

就是我在python里面写了一个rest-api,暴露出几个接口,供Java这边调。

但是不知道为什么算法部当时那边弄了个什么,导致暴露出的接口是https的

而Java通过restTemplate调https就会有证书问题,而最开始python工程下有三个证书,我是一头雾水。

位置是在python工程下的config的certificate。

下面有三个证书文件,一个是ca.crt,一个是pkcs8_server.key,还有一个是server.crt。

时间过得有点久,忘记这三个证书的区别了。

1. ca.crt:是证书颁发机构(CA)的根证书,用于验证服务器证书的真实性。客户端会使用它来验证服务器证书是否由受信任的证书颁发机构签发。

2. pkcs8_server.key:是服务器的私钥,用于加密和解密TLS/SSL握手消息中的数据。它应该是安全的,并且只有服务器才能访问它。

3. server.crt:是服务器的公钥证书,用于验证服务器的身份。它包含了服务器的公钥以及一些其他信息,如服务器的域名等。

最开始我以为这三个证书都要用,然后用pk12生成了一个,应该是要去linux环境下通过OpenSSL做,这种方法是行得通的

生成了的一个pk12证书是放在Java工程下,然后去使用这个证书,要配置私钥的。

后来同事说应该是不需要配私钥的,让我找找不用私钥的做法。

我后来找到了另外一种解决方案,其实只需要ca.crt就可以了。

 

简单说一下如何做的吧

使用方法

@Resource
private RestClient restClient;
RestTemplate restTemplate = SpringBeanContextUtil.getBean(RestClient.class).getRestTemplate();

配置

/**
 * RestClient配置python证书,用于调https接口
 */
@Component
@Slf4j
public class RestClient {
    private RestTemplate restTemplate;

    public RestTemplate getRestTemplate() {
        if (restTemplate == null) {
            this.restTemplate = new RestTemplate(getClientHttpRequestFactory());
        }
        return this.restTemplate;
    }

    private ClientHttpRequestFactory getClientHttpRequestFactory() {
        // 加载证书
        try (InputStream inputStream = getClass().getResourceAsStream("/cert/ca.crt")) {
            log.info("getClientHttpRequestFactory, load X.509");
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate caCert = (X509Certificate) cf.generateCertificate(inputStream);
            log.info("getClientHttpRequestFactory, caCert = {}", caCert);
            // 加载证书到 KeyStore
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            keyStore.setCertificateEntry("caCert", caCert);
            log.info("getClientHttpRequestFactory -> setCertificateEntry");

            // 创建 SSLContext
            SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(keyStore, null).build();
            log.info("getClientHttpRequestFactory -> sslContext");

            // 创建 RestTemplate
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,
                new String[] {"TLSv1.2"}, null, new NoopHostnameVerifier());
            log.info("getClientHttpRequestFactory -> socketFactory");
            HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
            log.info("getClientHttpRequestFactory -> httpClient");
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
            log.info("getClientHttpRequestFactory -> factory");
            factory.setConnectTimeout(5000);
            factory.setReadTimeout(5000);
            return factory;
        } catch (IOException | CertificateException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException ex) {
            log.error("getClientHttpRequestFactory", ex);
            throw new BaseException(ErrorCode.SYSTEM_EXCEPTION);
        }
    }
}

  

posted on 2024-03-20 16:13  沉浸深海  阅读(153)  评论(0)    收藏  举报