java.security.cert.CertificateException:没有主题备用名称;

4 java ssl wso2 ssl-certificate wso2-api-manager

我正在使用WSO2 API Managerversion 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
Run Code Online (Sandbox Code Playgroud)

现在我正在努力开发的java利用代码RestTemplate将连接到SSL protected sitecert verification,即,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());
    }
Run Code Online (Sandbox Code Playgroud)

我面临的错误。请建议我们如何以不安全的方式连接到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
Run Code Online (Sandbox Code Playgroud)

我们如何解决这个错误?偏离路线我的问题与javax.net.ssl.SSLHandshakeException类似:java.security.cert.CertificateException:没有主题替代名称

小智 9

可以通过应用以下代码来解决以下问题,这些代码以不安全的方式连接到受SSL保护的站点。(注意:为了使用cert启用连接到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());
    }
Run Code Online (Sandbox Code Playgroud)


小智 2

API Manager 1.9.1 支持 EOL 日期为 2019 年 8 月 31 日,所以如果您还没有,我强烈建议您更新到最新版本。

通常,如果您想要不安全的地址,您将需要使用 http。在 WSO2 中,https 配置为安全,您可以使用将SSL 证书添加到击键页面上的说明将后端客户端证书导入到客户端信任存储文件中。

您可能还会发现“配置密钥库”页面会有所帮助。

以不安全的方式调用 HTTPS 端点可能会导致安全漏洞,并且不是最佳实践。

祝你冒险顺利!