【java应用系统连接自有https证书(无法验证)的minio服务时报错问题处理过程】
1、PKIX path building failed: SunCertPathBuilderException: unable to find valid certification path to requested target
报错表示https证书无法验证,可能是证书过期,也可能是自有证书问题。博主这里属于第二种。
解决方法,把证书保存到本地keystore,具体:
(1)浏览器访问目标地址,导出数字证书
(2)把证书放到应用服务器上
(3)保存证书
keytool -import -alias 证书别名 -file 证书位置 -keystore 你的java安装目录/jre/lib/security/cacerts
示例:
keytool -import -alias mycert -file /opt/data/mycert.cer -keystore $JAVA_HOME/jre/lib/security/cacerts
密码:changeit 或者 changeme
添加后可以用以下命令确认证书已保存:
keytool -list -keystore 你的java安装目录/jre/lib/security/cacerts
示例:
keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
2、javax.net.ssl.SSLPeerUnverifiedException: Hostname xxx.com not verified:
安装证书后,又报了这个:服务器的ip地址跟证书中的ip地址不匹配的问题 (控制台打印出的报错中的CN地址即为证书ip地址)
解决方法:
(1)重新制作证书确保CN的ip地址跟服务器ip地址一致
(2)配置minio的OkHttp信任所有SSL证书,具体:
在生成MinioClient时指定自定义的OkHttpClient对象:
MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.httpClient(getUnsafeOkHttpClent())
.build()
自定义的OkHttpClient方法,参考自博客 :
https://blog.csdn.net/weixin_39288821/article/details/120917507
https://blog.csdn.net/u010445301/article/details/108058005
https://www.pianshen.com/article/14642043210/
import okhttp3.OkHttpClient;
import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
...
public static OkHttpClient getUnsafeOkHttpClent() throws KeyManagementException {
try {
final TrustManager[] trustAllCerts = 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[]{};
}
}
};
X509TrustManager x509TrustManager = (X509TrustManager) trustAllCerts[0];
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory,x509TrustManager);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
return builder.build();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
...
自此,问题解决~