我尝试使用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服务器。
答案 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上搜索此错误消息时首先点击!)。