简体   繁体   中英

Android: How do I programmatically DOWNLOAD an SSL certificate from a provided HTTPS URL?

            try {
                final SSLSocket sslSocket = (SSLSocket)SSLSocketFactory.getDefault().createSocket();
                Timber.e("RAWR: BEFORE CONNECT");
                sslSocket.connect(new InetSocketAddress("192.168.1.90", 8443));
                Timber.e("RAWR: AFTER CONNECT");
                final SSLSession session = sslSocket.getSession();
                Timber.e("RAWR: AFTER GET SESSION");
                for (Certificate certificate : session.getPeerCertificates()) {
                    Timber.e("RAWR found cert " + certificate);
                }
            } catch (SSLPeerUnverifiedException peer) {
                Timber.e("RAWR: UNVERIFIED PEER %S", peer.getMessage());
            } catch (IOException e) {
                Timber.e(e, "RAWR IOE %s", e.getMessage());
            }

I want to DOWNLOAD the certificates using the getPeerCertificates() but it throws SSLPeerUnverifiedException before it can get the certs.

The environments I'm dealing with have 100% self-signed certificates and they CANNOT be loaded on device before hand. The idea is customers do not have to load this themselves, and the app itself should download it and prompt the user whether to accept it or not.

The easiest way is to let Java download the server certificate for you and then just grab and save it.

This can be done by using a custom X509TrustManager implementation as it it shown for example in this answer .

The part you need to modify is checkServerTrusted :

public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
    X509Certificate serverCert = certs[0]; // as far as I remember the server leaf certificate is always the first entry in this array
    // save the certificate to some field you can access from outside of the trust manager.
    throw new CertificateException(); // we don't want to establish the HTTPS connection so by throwing the exception we can abort the TLS handshake here
}

In the end you only have to call getEncoded() on the saved serverCert to get it's ASN.1 DER encoded representation as byte[] which you can save to a file like server.cer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM