java中发送https请求报错的问题记录
问题1 the trustAnchors parameter must be non-empty
import org.apache.commons.io.IOUtils;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.net.URL;
public class TestHttps {
public static void main(String[] args) throws IOException {
String url = "https://xxx";
HttpsURLConnection http = (HttpsURLConnection) new URL(url).openConnection();
http.connect();
String resp = IOUtils.toString(http.getInputStream(), "UTF-8");
System.out.println(resp);
}
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
java低版本有这个问题,高版本没遇到过,解决方法如下
import org.apache.commons.io.IOUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class TestHttps {
public static void main(String[] args) throws IOException {
String url = "https://xxx";
HttpsURLConnection http = (HttpsURLConnection) new URL(url).openConnection();
http.setSSLSocketFactory(sslSocketFactory());
http.setHostnameVerifier(hostnameVerifier());
http.connect();
String resp = IOUtils.toString(http.getInputStream(), "UTF-8");
System.out.println(resp);
}
private static HostnameVerifier hostnameVerifier() {
return (s, sslSession) -> true;
}
private static SSLSocketFactory sslSocketFactory() {
X509TrustManager 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];
}
};
TrustManager[] tm = new TrustManager[]{trustManager};
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, tm, new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
跳过 SSL 证书验证。
问题2 Unrecognized SSL message, plaintext connection
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
原因是对方不接受https的请求,改为http即可。
问题3 No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:106)
at sun.security.ssl.TransportContext.kickstart(TransportContext.java:245)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:410)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:389)
原因是:服务器没有对应的 SSL 协议,解决方法如下
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
修改为
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1","TLSv1.1","TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
添加支持的协议。
参考
HTTP出现:No appropriate protocol (protocol is disabled or cipher suites are inappropriate)