【发布时间】:2015-07-26 20:12:50
【问题描述】:
我尝试使用 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,我仍然得到 p>
javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:不存在主题替代名称
我尝试使用 SOAPUI 5.1.3,并且优先使用> ssl,我设置了密钥库和密钥库密码(但没有设置信任库的地方),这次我可以通过 https 连接到我的目标服务器!
所以
1)为什么soapUI 5.1.3不需要设置truststore(只需要keystore),却依然可以连接到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 在 sun.security.ssl.Alerts.getSSLException(未知来源)
但是密钥库应该是正确的,因为我在 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服务器了。
【问题讨论】:
-
'不安全的重新协商'与证书无关。