我有一个Java Web服务客户端,该客户端通过HTTPS使用Web服务。
import javax.xml.ws.Service; @WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...") public class ISomeService extends Service { public ISomeService() { super(__getWsdlLocation(), ISOMESERVICE_QNAME); }
当我连接到服务URL(https://AAA.BBB.CCC.DDD:9443/ISomeService)时,出现异常java.security.cert.CertificateException: No subject alternative names present。
java.security.cert.CertificateException: No subject alternative names present。
要解决此问题,我首先运行openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt并在file中获取以下内容certs.txt:
openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt
certs.txt
CONNECTED(00000003) --- Certificate chain 0 s:/CN=someSubdomain.someorganisation.com i:/CN=someSubdomain.someorganisation.com -----BEGIN CERTIFICATE----- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -----END CERTIFICATE----- --- Server certificate subject=/CN=someSubdomain.someorganisation.com issuer=/CN=someSubdomain.someorganisation.com --- No client certificate CA names sent --- SSL handshake has read 489 bytes and written 236 bytes --- New, TLSv1/SSLv3, Cipher is RC4-MD5 Server public key is 512 bit Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : RC4-MD5 Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Session-ID-ctx: Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Key-Arg : None Start Time: 1382521838 Timeout : 300 (sec) Verify return code: 21 (unable to verify the first certificate) ---
AFAIK,现在我需要
如果是这样,我如何才能使第1步中的证书与基于IP的地址(AAA.BBB.CCC.DDD)一起使用?
我通过使用此处介绍的方法禁用HTTPS检查来解决此问题:
我将以下代码放入ISomeService该类中:
ISomeService
static { disableSslVerification(); } private static void disableSslVerification() { try { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { public java.security.cert.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(); } }
由于我https://AAA.BBB.CCC.DDD:9443/ISomeService仅将它们用于测试目的,所以这是一个足够好的解决方案。
https://AAA.BBB.CCC.DDD:9443/ISomeService