以编程方式将服务器证书信息添加到 Trust Manager Android

Posted

技术标签:

【中文标题】以编程方式将服务器证书信息添加到 Trust Manager Android【英文标题】:Add Server Certificate Information to Trust Manager Android Programmatically 【发布时间】:2015-07-22 22:14:27 【问题描述】:

我是这个 SSLX509Certificate 概念的新手。我所需要的是,有没有办法从给定的Url 获取证书信息

例如:如果用户输入了https://www.google.com,那么我需要以编程方式获得该证书信息。

编辑:

最后,我得到了来自服务器的证书信息

现在,我的问题是:

1.如何检查证书是否可信?

2.如何将证书添加到信任管理器?

3. 即使它是不受信任的证书,如果用户想继续使用它,那么我需要将证书添加到信任管理器。我怎样才能做到这一点?

4.为了检查证书是否可信,我们真的需要另一个证书来比较吗?

我对这些X.509 Certificate.非常陌生

我们将非常感谢任何帮助。

编辑:

这是我尝试过的。但是,他们都没有帮助我。我需要获得证书是否受信任。

X509TrustManager trustManager = new X509TrustManager() 
                @Override
                public void checkClientTrusted(X509Certificate[] chain,
                        String authType) throws CertificateException 
                    for (TrustManager tm : managers) 
                        if (tm instanceof X509TrustManager) 
                            ((X509TrustManager) tm).checkClientTrusted(
                                    chain, authType);
                        
                    
                

                @Override
                public void checkServerTrusted(X509Certificate[] chain,
                        String authType) 

                    for (X509Certificate cert : chain) 

                        final String mCertificatinoType = cert.getType();
                        Date afterDate = cert.getNotAfter();
                        Date beforeDate = cert.getNotBefore();
                        Date currentDate = new Date();

                        try 
                            cert.checkValidity(new Date());
                         catch (CertificateExpiredException e) 
                            LoginActivity.isExpired = true;
                            e.printStackTrace();
                         catch (CertificateNotYetValidException e) 
                            LoginActivity.isInValid = true;
                            e.printStackTrace();
                        

                        try 
                            cert.verify(trustedRoot.getPublicKey());
                         catch (InvalidKeyException e) 
                            e.printStackTrace();
                         catch (CertificateException e) 
                            e.printStackTrace();
                         catch (NoSuchAlgorithmException e) 
                            e.printStackTrace();
                         catch (NoSuchProviderException e) 
                            e.printStackTrace();
                         catch (SignatureException e) 
                            e.printStackTrace();
                        

                        try 
                            if (cert.getIssuerX500Principal().equals(
                                    trustedRoot.getIssuerX500Principal())) 

                            
                            cert.verify(trustedHost.getPublicKey());
                         catch (InvalidKeyException e) 
                            e.printStackTrace();
                         catch (CertificateException e) 
                            e.printStackTrace();
                         catch (NoSuchAlgorithmException e) 
                            e.printStackTrace();
                         catch (NoSuchProviderException e) 
                            e.printStackTrace();
                         catch (SignatureException e) 
                            e.printStackTrace();
                        

                        if (afterDate.compareTo(currentDate)
                                * currentDate.compareTo(beforeDate) > 0) 
                         else 

                        

                        if (cert.getIssuerX500Principal().equals(
                                trustedRoot.getIssuerX500Principal())) 
                            return;
                        
                    

                    // for (X509Certificate cert : chain) 
                    // URL url;
                    // String host = "";
                    // if (baseHostString.equalsIgnoreCase("")) 
                    // final Settings settings = mApplication
                    // .getSettings();
                    // try 
                    // url = new URL(
                    // settings.serverAddress.toString());
                    // host = url.getAuthority();
                    //  catch (MalformedURLException e) 
                    // e.printStackTrace();
                    // 
                    //  else 
                    //
                    // 
                    //
                    // String dn = cert.getSubjectDN().getName();
                    // String CN = getValByAttributeTypeFromIssuerDN(dn,
                    // "CN=");
                    // if (CN.equalsIgnoreCase(host)) 
                    // if (cert.getIssuerX500Principal().equals(
                    // trustedRoot.getIssuerX500Principal())) 
                    // return;
                    //  else 
                    // 
                    //  else 
                    // 
                    // 
                    for (TrustManager tm : managers) 
                        if (tm instanceof X509TrustManager) 
                            try 
                                ((X509TrustManager) tm).checkServerTrusted(
                                        chain, authType);
                             catch (CertificateException e) 
                                e.printStackTrace();
                            
                        
                    

                

                @Override
                public X509Certificate[] getAcceptedIssuers() 
                    ArrayList<X509Certificate> issuers = new ArrayList<>();
                    for (TrustManager tm : managers) 
                        if (tm instanceof X509TrustManager) 
                            issuers.addAll(Arrays
                                    .asList(((X509TrustManager) tm)
                                            .getAcceptedIssuers()));
                        
                    
                    return issuers.toArray(new X509Certificate[issuers
                            .size()]);
                

            ;

【问题讨论】:

Using openssl to get the certificate from a server的可能重复 您想使用 android Java 还是使用 OpenSSL?而拿到证书后你想做什么? 使用 Android Java...我需要将该证书添加到信任管理器中......并且也应该允许该不受信任的服务器证书@jww。您分享的链接不同 @jww 这不是那个的副本。 @EpicPandaForce: 有没有办法检查 X509 证书是否可信? 【参考方案1】:

终于破解了!

                X509TrustManager trustManager = new X509TrustManager() 
                @Override
                public void checkClientTrusted(X509Certificate[] chain,
                        String authType) throws CertificateException 
                    for (TrustManager tm : managers) 
                        if (tm instanceof X509TrustManager) 
                            ((X509TrustManager) tm).checkClientTrusted(
                                    chain, authType);
                        
                    
                

                @Override
                public void checkServerTrusted(
                        final X509Certificate[] chain, String authType) 

                    for (X509Certificate cert : chain) 

                        final String mCertificatinoType = cert.getType();
                        Date afterDate = cert.getNotAfter();
                        Date beforeDate = cert.getNotBefore();
                        Date currentDate = new Date();

                        try 
                            cert.checkValidity(new Date());
                         catch (CertificateExpiredException e) 
                            isExpired = true;
                            e.printStackTrace();
                         catch (CertificateNotYetValidException e) 
                            isInValid = true;
                            e.printStackTrace();
                        

                        if (afterDate.compareTo(currentDate)
                                * currentDate.compareTo(beforeDate) > 0) 
                            isExpired = false;
                         else 
                            isExpired = true;
                        

                        String dn = cert.getSubjectDN().getName();
                        String CN = getValByAttributeTypeFromIssuerDN(dn,
                                "CN=");

                        String host = "";
                        if (TextUtils.isEmpty(query)) 
                            if (baseHostString.equalsIgnoreCase("")) 
                                final Settings settings = mApplication
                                        .getSettings();
                                try 
                                    URL url = new URL(
                                            settings.serverAddress
                                                    .toString());
                                    host = url.getAuthority();
                                    if (host.contains(String.valueOf(url
                                            .getPort()))) 
                                        String toBeReplaced = ":"
                                                + url.getPort();
                                        host = host.replace(toBeReplaced,
                                                "");
                                    
                                 catch (MalformedURLException e) 
                                    e.printStackTrace();
                                
                             else 
                                try 
                                    URL url = new URL(baseHostString);
                                    host = url.getAuthority();
                                    if (host.contains(String.valueOf(url
                                            .getPort()))) 
                                        String toBeReplaced = ":"
                                                + url.getPort();
                                        host = host.replace(toBeReplaced,
                                                "");
                                    
                                 catch (MalformedURLException e) 
                                    e.printStackTrace();
                                
                            
                         else 
                            try 
                                URL url = new URL(query);
                                host = url.getAuthority();
                                if (host.contains(String.valueOf(url
                                        .getPort()))) 
                                    String toBeReplaced = ":"
                                            + url.getPort();
                                    host = host.replace(toBeReplaced, "");
                                
                             catch (MalformedURLException e) 
                                e.printStackTrace();
                            
                        

                        if (CN.equalsIgnoreCase(host)) 
                            isHostMisMatch = false;
                         else 
                            isHostMisMatch = true;
                        

                        for (TrustManager tm : managers) 
                            if (tm instanceof X509TrustManager) 
                                try 
                                    ((X509TrustManager) tm)
                                            .checkServerTrusted(chain,
                                                    authType);
                                 catch (CertificateException e) 
                                    if (e.getMessage() != null
                                            && e.getMessage()
                                                    .contains(
                                                            "Trust anchor for certification path not found.")) 
                                        isNotTrusted = true;
                                        mApplication
                                                .setCurrentCertificate(chain);
                                    
                                    e.printStackTrace();
                                
                            
                        

                        if (cert.getIssuerX500Principal().equals(
                                trustedRoot.getIssuerX500Principal())) 
                            return;
                        
                    

                

                @Override
                public X509Certificate[] getAcceptedIssuers() 
                    ArrayList<X509Certificate> issuers = new ArrayList<>();
                    for (TrustManager tm : managers) 
                        if (tm instanceof X509TrustManager) 
                            issuers.addAll(Arrays
                                    .asList(((X509TrustManager) tm)
                                            .getAcceptedIssuers()));
                        
                    
                    return issuers.toArray(new X509Certificate[issuers
                            .size()]);
                

            ;

谢谢大家。

【讨论】:

以上是关于以编程方式将服务器证书信息添加到 Trust Manager Android的主要内容,如果未能解决你的问题,请参考以下文章

如何从trust.p12证书文件中获取SSL证书主题,颁发者,开始日期和过期日期

以编程方式完成时,http add sslcert失败

以编程方式将标签添加到 Swift 中的消息应用程序?

按钮按下以编程方式将新行添加到 ListView,如何?

如何以编程方式将证书添加为当前JVM实例的受信任

如何使用 c# 以编程方式将证书安装到本地机器存储中?