HttpsURLConnection - 在Android应用程序中信任服务器

时间:2016-03-28 10:42:17

标签: android https

我目前正在开发一款Android应用(Android Studio 2.0),它将通过HTTPS(使用javax.net.ssl.HttpsURLConnection)连接到我的服务器(Glassfish 4.1,Netbeans 8.1)。目前这一切都在我的本地网络(智能手机+笔记本电脑)上运行。我现在遇到的问题是:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我认为因为我的Android应用程序还不信任服务器。我该如何去做它确实信任服务器?

在某些官方文档(http://developer.android.com/training/articles/security-ssl.html)和其他指南中,我看到过提到Keystores或使用.crt文件。但是我在哪里可以获得其中任何一个,如何在移动设备上获取它们?

目前我的代码如下:

public static HttpsURLConnection setupHttpsConnection(URL url, Context context) {
    try {
        // Load CAs from an InputStream
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new BufferedInputStream(context.getAssets().open("localhost.crt"));
        Certificate ca;
        try {
            ca = cf.generateCertificate(caInput);
            Log.d(LOG_TAG, "> setupHttpsConnection > ca.getSubjectDN = " + ((X509Certificate) ca).getSubjectDN());
        } finally {
            caInput.close();
        }

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        /*
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                HostnameVerifier hv =
                        HttpsURLConnection.getDefaultHostnameVerifier();
                return hv.verify("192.168.0.121", session);
            }
        };
        */

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        //urlConnection.setHostnameVerifier(hostnameVerifier);
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
        return urlConnection;

    } catch (Exception e) {
        e.printStackTrace();
        Log.d(LOG_TAG, e.toString());
        return null;
    }
}

然后在另一个地方我打电话:

urlConnection = Utility.setupHttpsConnection(url, context);
urlConnection.connect(); // <-- Exception thrown here!

0 个答案:

没有答案