证书中的主机名不匹配?

我尝试使用自签名证书连接到服务器。 我使用此代码接受所有证书。

public class CertificateAcceptor { public void initializeTrustManager() { try { SSLContext context = SSLContext.getInstance("SSL"); context.init(null, createTrustManager(), new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } } private TrustManager[] createTrustManager() { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // leave blank to trust all clients } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // leave blank to trust all servers for (X509Certificate c : chain) { System.out.println(c.toString()); } } } }; return trustAllCerts; } } 

但是,我得到以下错误:

 javax.net.ssl.SSLException: hostname in certificate didn't match:  !=  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:220) at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:149) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:130) at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:339) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123) at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576) 

我确定我的证书代码已执行,那么可能是什么问题?

您可以使用SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER

 SSLSocketFactory sf = new SSLSocketFactory( SSLContext.getInstance("TLS"), SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); Scheme sch = new Scheme("https", 443, sf); httpclient.getConnectionManager().getSchemeRegistry().register(sch); HttpGet httpget = new HttpGet("https://host/"); ... ... 

ALLOW_ALL不是正确的答案。 您应该使用带有ext扩展名的keytool来设置具有正确名称的证书:

 keytool -genkeypair \ -keystore keystore.jks \ -dname "CN=OLEKSIYS-W3T, OU=Sun Java System Application Server, O=Sun Microsystems, L=Santa Clara, ST=California, C=US" \ -keypass changeit \ -storepass changeit \ -keyalg RSA \ -keysize 2048 \ -alias default \ -ext SAN=DNS:localhost,IP:127.0.0.1 \ -validity 9999 

有关详细信息,请参阅http://tersesystems.com/2014/03/23/fixing-hostname-verification/ 。

您是否尝试过调用HttpsURLConnection setDefaultHostnameVerifier

请参阅此链接以获取示例: 在Android上接受HTTPs证书

Prashant的答案可能不起作用,因为您还需要初始化SSLContext

我会这样做的,

 SSLSocketFactory sf=null ; SSLContext sslContext = null; StringWriter writer; try { sslContext = SSLContext.getInstance("TLS") ; sslContext.init(null,null,null); } catch (NoSuchAlgorithmException e) { // } catch (KeyManagementException e){ // } try{ sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); } catch(Exception e) { // } Scheme scheme = new Scheme("https",443,sf); httpClient.getConnectionManager().getSchemeRegistry().register(scheme); 

我的问题是,Java SE 6或更小版本不支持SNI。 这意味着,一个IP只能有一个ssl证书。 但在我的服务器上,有3个不同的apis具有不同的ssl证书。 Java SE 7或更高版本支持SNI,一切正常。 (或者只在服务器上运行一个api)