1.证书错误
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
2.生成客户端证书
openssl x509 -in <(openssl s_client -connect 192.168.11.19:8101 -prexit 2>/dev/null) -out 11_19_8101.crt
会在当前文件夹下生成11_19_8101.crt;如果是其它网址,相应的替换192.168.11.19:8101
3.证书导入到jvm
到{jdk_home}/jre/bin下,执行下面命令,密码输入changeit,后面提示是否信任该证书,输入Y
keytool -keystore ..\lib\security\cacerts -import -alias 192.168.11.19 -file /home/11_19_8101.crt
4.验证jdk证书是否生效
验证http请求的java
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @description http request test
* javac HttpTest.java
* java HttpTest url param
* @date 2024/08/21
*/
public class HttpTest {
public static void main(String[] args) {
try {
URL url = new URL(args[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
os.write(args[1].getBytes());
InputStream is = connection.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = is.read(buffer)) != -1) {
System.out.println("Read " + bytesRead + " bytes");
System.out.println(new String(buffer,"UTF-8"));
}
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
System.out.println("http request success");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
在服务器上执行命令
javac HttpTest.java
java HttpTest https://192.168.xx.xx:6666/callback/basic {"name":"123456"}
证书问题未修正时,会报出下面问题;修正后运行将打印正常返回
5.忽略ssl证书验证
下面代码为忽略ssl证书错误的http请求工具类,或者仿照下面修改自己项目中的请求工具类
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
/**
* @Description: HttpUtils
* @Author: zhanggw
* @CreateDate: 2024/8/21
*/
public class HttpUtils {
public static void main(String[] args) {
String result = postIgnoreSSl(args[0], args[1], null);
System.out.println("result:" + result);
}
public static String postIgnoreSSl(String uri, String params, Map<String, String> headers) {
Reader in = null;
try {
URL url = new URL(uri);
byte[] postDataBytes = params.getBytes(StandardCharsets.UTF_8);
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
});
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.setConnectTimeout(1000);
conn.setReadTimeout(1000);
if (headers != null && !headers.isEmpty()) {
Set<String> keys = headers.keySet();
for (String key : keys) {
conn.setRequestProperty(key, headers.get(key));
}
}
conn.getOutputStream().write(postDataBytes);
int code = conn.getResponseCode();
if (code == 200) {
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
} else {
in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
}
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; ) {
sb.append((char) c);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager customTrustManager = new customTrustManager();
trustAllCerts[0] = customTrustManager;
javax.net.ssl.SSLContext sslContext = javax.net.ssl.SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
}
static class customTrustManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
}
参考资料:
ssl - Java: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target - Stack Overflow