安卓系统验证TSL服务器证书

0 人关注

我有以下任务要实现,但网上似乎没有一个好的方法显示如何优雅地做到这一点。(要么是使用旧的HTTPClient,要么是解决方案根本就不太相关)谁能提供这方面的建议或解决方案?

给定一个网址,我的应用程序需要获取相关的TLS服务器证书并完成以下任务。

  • Retrieve the subject field in the certificate
  • Check the TLS server certificate is not expired
  • Check the TLS server certificate is valid by making query to the Issuing CA's OCSP service.
  • HttpURLConnection和URLConnection似乎与我要完成的任务有关,但它不确定如何检索服务器证书。

    我知道以下关于Android中的服务器证书的网站

    http://www.normalesup.org/~george/articles/manual_https_cert_check_on_android.html

    Receive & Validate certificate from server HTTPS - android

    1 个评论
    你不应该需要这些,除非你做一些非常不寻常的事情,HTTPSUrlConnection的代码已经做了所有这些。
    android
    android-studio
    ssl
    tls1.2
    Stephen Fong
    Stephen Fong
    发布于 2021-09-16
    1 个回答
    Stephen Fong
    Stephen Fong
    发布于 2021-09-17
    已采纳
    0 人赞同

    事实证明,你可以使用getServerCertificates()来检索证书链,它是在你启动HttpsURLConnection后获取的。HttpsURLConnection实现了TLS,这样你就可以确认证书是真实的,你与服务器的通信是保密的,数据的完整性得到了保留。

    public void verifyCertificate(View view) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Log.d("DEBUG", "Hello there");
                    try {
                        aFunctionWithCoolName("https://urlOfTheSiteYouWannaCheck.com");
                        Log.d("DEBUG", "Executed aFancyFunctionWithCoolName without any exceptions");
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.d("DEBUG", "IOException");
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                        Log.d("DEBUG", "NoSuchAlgorithmException");
                    } catch (CertificateEncodingException e) {
                        e.printStackTrace();
                        Log.d("DEBUG", "CertificateEncodingException");
                    } catch (CertificateParsingException e) {
                        e.printStackTrace();
                        Log.d("DEBUG", "CertificateParsingException");
                    } catch (Exception e) {
                        Log.wtf("DEBUG", "Too sad, I don't know what is happening :(");
            }).start();
        private static void aFunctionWithCoolName(String httpsURL) throws IOException, NoSuchAlgorithmException, CertificateEncodingException, CertificateParsingException {
            final HttpsURLConnection con = (HttpsURLConnection) (new URL(httpsURL)).openConnection();
            con.setRequestMethod("GET");
            con.setConnectTimeout(5000);
            con.connect();
            // https://developer.android.com/reference/java/security/cert/X509Certificate
            // https://developer.android.com/reference/java/security/cert/Certificate
            // https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection#getServerCertificates()
            final Certificate[] certs = con.getServerCertificates();
            final Certificate subjectCert = certs[0];
            final Certificate rootCert = certs[certs.length-1];
            if (subjectCert instanceof X509Certificate && rootCert instanceof X509Certificate) {
                X509Certificate sc = (X509Certificate) subjectCert;
                X509Certificate rc = (X509Certificate) rootCert;
                printX509CertificateDetail(sc);
        public static void printX509CertificateDetail(X509Certificate cert) {
            Log.d("DEBUG", "===========================================");
            Log.d("DEBUG - Subject DN", cert.getSubjectX500Principal().toString());
            Log.d("DEBUG - Subject CN", getSubjectCommonName(cert));
            Log.d("DEBUG - URL DN", url.getHost());