解决 Java CertificateParsingException: 空颁发者 DN 错误 - RestTemplate 示例
java.security.cert.CertificateParsingException: Empty issuer DN not allowed in X509Certificates 是由于证书的颁发者(DN)为空导致的异常。解决这个问题的方法是使用有效的证书。
以下是一个使用 RestTemplate 发送 HTTP 请求时,忽略证书验证的示例代码:
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class Main {
public static void main(String[] args) {
// 创建一个信任所有证书的 SSL 上下文
SSLContext sslContext = createTrustAllSSLContext();
// 创建一个忽略证书验证的 RestTemplate
RestTemplate restTemplate = createRestTemplate(sslContext);
// 发送 HTTP 请求
String url = 'https://example.com/api';
String response = restTemplate.getForObject(url, String.class);
System.out.println(response);
}
private static SSLContext createTrustAllSSLContext() {
try {
SSLContext sslContext = SSLContext.getInstance('TLS');
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}}, null);
return sslContext;
} catch (Exception e) {
throw new RuntimeException('Failed to create TrustAll SSL context', e);
}
}
private static RestTemplate createRestTemplate(SSLContext sslContext) {
try {
// 创建一个信任所有主机名的主机名验证器
HostnameVerifier hostnameVerifier = (s, sslSession) -> true;
// 创建一个忽略证书验证的 SSL 套接字工厂
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
// 创建一个简单的客户端 HTTP 请求工厂
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(5000);
requestFactory.setReadTimeout(5000);
requestFactory.setTaskExecutor(new SimpleAsyncTaskExecutor());
// 创建一个 RestTemplate 并设置相关配置
RestTemplate restTemplate = new RestTemplate(requestFactory);
restTemplate.setRequestFactory(requestFactory);
restTemplate.setInterceptors(Collections.singletonList(new LoggingClientHttpRequestInterceptor()));
restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
// 设置 SSL 套接字工厂和主机名验证器
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
return restTemplate;
} catch (Exception e) {
throw new RuntimeException('Failed to create RestTemplate', e);
}
}
}
上述示例代码中,我们创建了一个信任所有证书的 SSL 上下文,并使用该上下文创建了一个忽略证书验证的 RestTemplate。这样,我们就可以发送 HTTP 请求而不需要验证服务器的证书。
请注意,忽略证书验证是不安全的,仅在开发和测试环境中使用。在生产环境中,应该使用有效的证书来保证通信的安全性。

原文地址: https://www.cveoy.top/t/topic/qw1x 著作权归作者所有。请勿转载和采集!