证书中的主机名不匹配?

8 java

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

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,我得到以下错误:

javax.net.ssl.SSLException: hostname in certificate didn't match: <xyz.ch> != <localhost>
    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)
Run Code Online (Sandbox Code Playgroud)

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

Wil*_*ent 17

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
Run Code Online (Sandbox Code Playgroud)

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


Pra*_*ate 8

你可以用 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/");
...
...
Run Code Online (Sandbox Code Playgroud)

  • 这是一个错误的答案.您应该使用带有`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 s1as\-ext SAN = DNS:localhost,IP:127.0 .0.1\-validity 9999```并查看http://tersesystems.com/2014/03/23/fixing-hostname-verification/ (7认同)
  • @Jackson比这更糟糕.联邦贸易委员会以这种方式起诉人们禁用安全.http://www.ftc.gov/news-events/press-releases/2014/03/fandango-credit-karma-settle-ftc-charges-they-deceived-consumers (3认同)
  • 这肯定有用,但@WillSargent是对的.如果您使用"全部允许"方法,您的应用就会变得脆弱.对于不太受欢迎但在工作/自由职业项目中要小心的应用程序,你可能会很好. (2认同)