allowUnsafeRenegotiation,但仍然是CertificateException

时间:2015-05-15 02:10:29

标签: java ssl https

我尝试使用SOAPConnection来调用https,我已经指向keystore和truststore,如下所示:

    System.setProperty("javax.net.ssl.keyStore", "C:/kei/tasks/MIP/Cert/ccc_acp.keystore");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    System.setProperty("javax.net.ssl.trustStore", "C:/kei/tasks/MIP/Cert/trusteaistore.keystore");
    System.setProperty("javax.net.ssl.trustStorePassword", "password");
    System.setProperty("javax.net.debug", "all");

但我还是得到了

  

javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:不存在主题替代名称

我谷歌并找到以下临时解决方案

System.setProperty( "sun.security.ssl.allowUnsafeRenegotiation", "true" );

但即使我将allowUnsafeRenegotation设置为true,我仍然得到

  

javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:不存在主题替代名称

我尝试使用SOAPUI 5.1.3,并且优先使用> ssl,我设置了密钥库和密钥库密码(但没有设置信任库的地方),这次我可以通过https连接到我的目标服务器!

所以

1)为什么soapUI 5.1.3不需要设置truststore(但只能设置密钥库),但仍然可以连接到https服务器?

2)为什么使用系统属性指向同一个密钥库,但我无法使用SOAPConnection连接到https服务器?

3)为什么我将allowUnsafeRenegotitation系统属性设置为true,但它似乎仍然检查公共证书。 https服务器,并返回CertificateException?

***************** 2015年5月15日编辑

我在这里发布代码

public static void main(String args[]){ 
    System.setProperty("javax.net.ssl.keyStore", "C:/kei/tasks/MIP/Cert/ccc_acp.keystore");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    MipCccSoapTest mipCccSoapTest = new MipCccSoapTest();
    mipCccSoapTest.testHttpConnection();        
}

private void testHttpConnection(){
    try{
        doTrustToCertificates();            
         URL url = new URL("https://10.7.3.43:9443/iboss/CustomerCareM1");
         HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); 
         HttpsURLConnection.getDefaultSSLSocketFactory();
         System.out.println("ResponseCoede ="+conn.getResponseCode());
    }catch(Exception ex){
        ex.printStackTrace();
    }
    System.exit(0);
    //end testing
}

// trusting all certificate 
 public void doTrustToCertificates() throws Exception {
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }
            }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
            }
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
}

我收到以下错误

  

javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure       at sun.security.ssl.Alerts.getSSLException(Unknown Source)

但密钥库应该是正确的,因为我在SOAPUI 5.1.3中使用相同的密钥库,可以成功调用服务器。

**************** 2015年5月18日编辑*************

在我注释掉以下代码后

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }
            }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

它现在可以连接到https服务器。

1 个答案:

答案 0 :(得分:2)

  

javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:不存在主题替代名称

这是服务器证书的问题。您需要通过添加具有适当信息的主题备选部分来修复它,以便可以成功验证它。它与信任链无关,因此对keyStore或trustStore没有任何更改有帮助。如果知道服务器URL或证书,可能会提供更多信息。

  

System.setProperty(“sun.security.ssl.allowUnsafeRenegotiation”,“true”);

这是TLS协议级别的事情,与证书验证无关。

如果您无法修复服务器证书,请参阅SSLHandshakeException: No subject alternative names present以获取可能的解决方法(在Google上搜索此错误消息时首先点击!)。