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)

posted @ 2024-04-05 21:27  strongmore  阅读(1233)  评论(0编辑  收藏  举报