繁体   English   中英

Android:如何以编程方式从提供的 HTTPS URL 下载 SSL 证书?

[英]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());
            }

我想使用 getPeerCertificates() 下载证书,但它会在获取证书之前抛出 SSLPeerUnverifiedException。

我正在处理的环境具有 100% 自签名证书,它们不能事先加载到设备上。 这个想法是客户不必自己加载它,应用程序本身应该下载它并提示用户是否接受它。

最简单的方法是让 Java 为您下载服务器证书,然后抓取并保存它。

这可以通过使用自定义 X509TrustManager 实现来完成,例如this answer中所示。

您需要修改的部分是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
}

最后,您只需在保存的 serverCert 上调用getEncoded()即可将其 ASN.1 DER 编码表示为byte[] ,您可以将其保存到server.cer之类的文件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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