【问题标题】:java.security.cert.CertificateException: No subject alternative names present;java.security.cert.CertificateException:不存在主题替代名称;
【发布时间】:2016-01-17 18:19:44
【问题描述】:

我正在使用WSO2 API Manager 版本1.9.1。在这个工具中,我发布了我的示例项目(即proxied)并订阅该项目以获取消费者密钥和秘密。该工具还为我提供了 CURL 命令,效果很好。

下面的 CURL 命令运行良好。

curl -k -d "grant_type=password&username=XXXXX&password=XXXXX" -H "Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, Content-Type: application/x-www-form-urlencoded" https://XXXXXXXXXXX:XXXX/token

现在我正在尝试使用RestTemplate 开发java 代码,它将在没有cert verification 的情况下连接到SSL protected site,即insecure 以查看上述CURL 命令的方式。 到目前为止,我开发了以下代码,但是当我运行时,我看到了以下错误。

public static void main(String[] args) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", "application/json");
        headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
        headers.add("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

        String url = "https://XXXXXXXXXXXXXX:XXXX/token";

        String data = "grant_type=password&username=XXXXX&password=XXXXX";

        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> entity = new HttpEntity<String>(data,headers);
        HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        System.out.println("RESPONSE : "+response.getBody());
    }

我面临的错误。 请建议我们如何以不安全的方式连接到 SSL 站点,与 curl 命令相同?

Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://XXXXXXXXXXX:8243/token":java.security.cert.CertificateException: No subject alternative names present; nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:580)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:448)
    at com.java.wso2.TokenDemo.main(TokenDemo.java:74)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1937)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1478)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1050)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:81)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:569)
    ... 3 more

我们如何解决这个错误?偏离路线我的问题与javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present 不相似

【问题讨论】:

    标签: java ssl wso2 ssl-certificate wso2-am


    【解决方案1】:

    以下问题可以通过应用以下代码来解决,这些代码以不安全的方式连接到受 SSL 保护的站点。 (注意:要使用 cert enable 连接到 SSL 站点,您需要添加 tomcat SSL 配置)。

    以下代码可以正常工作。

    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;
    import org.springframework.web.client.RestTemplate;
    
    
    static {
            disableSslVerification();
        }
    
        private static void disableSslVerification() {
            try{
                // Create a trust manager that does not validate certificate chains
                TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
                };
    
                // Install the all-trusting trust manager
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    
                // Create all-trusting host name verifier
                HostnameVerifier allHostsValid = new HostnameVerifier() {
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                };
    
                // Install the all-trusting host verifier
                HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Accept", "application/json");
            headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
            headers.add("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    
            String url = "https://XXXXXXXXXXXXX:XXXX/token";
    
            String dataJSON = "grant_type=password&username=XXXXX&password=XXXXX";
    
            RestTemplate restTemplate = new RestTemplate();
            HttpEntity<String> entity = new HttpEntity<String>(dataJSON,headers);
            HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
            System.out.println("O/P : "+response.getBody());
        }
    

    【讨论】:

    • 这对我不起作用。在这里,我们已将所有内容添加到 httpRLConnection,但在 httpEntity 中没有使用。你能不能再解释一下。
    • @Nutan 如果您注意到他在静态上下文中编写了“disableSslVerification”,那么它应该可以按预期工作
    • 这对我来说可以忽略 SSL
    猜你喜欢
    • 2014-04-02
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2020-07-08
    • 2014-04-25
    • 2023-04-11
    • 2019-05-09
    • 1970-01-01
    相关资源
    最近更新 更多