【问题标题】:Detect installed certificate in my android device在我的 android 设备中检测已安装的证书
【发布时间】:2013-01-31 02:38:04
【问题描述】:

当应用程序启动时,我正在我的应用程序中安装证书。我浏览了以下几个链接并成功安装了证书。

我知道我们无法在没有用户交互的情况下静默安装证书。目前我不知道每次用户打开我的应用时如何停止提示。

每当我的应用程序当前每次要求用户安装证书时启动。有什么方法可以检测证书(在这种情况下是我的证书)是否已经安装,以编程方式。

代码 sn-p 我在我的应用中安装证书的地方

private void installCertificate()
    {
        try 
        {
            BufferedInputStream bis = new BufferedInputStream(getAssets().open(MY_CERT));
            byte[] keychain = new byte[bis.available()];
            bis.read(keychain);

            Intent installIntent = KeyChain.createInstallIntent();
            X509Certificate x509 = X509Certificate.getInstance(keychain);
            installIntent.putExtra(KeyChain.EXTRA_CERTIFICATE, x509.getEncoded());
            installIntent.putExtra(KeyChain.EXTRA_NAME, MY_CERT);
            startActivityForResult(installIntent, INSTALL_KEYCHAIN_CODE);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        catch (CertificateException e) 
        {
            e.printStackTrace();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        if (requestCode == INSTALL_KEYCHAIN_CODE) 
        {
            switch (resultCode) 
            {  
                case Activity.RESULT_OK:
                    doTheTask();
                    break;
                case Activity.RESULT_CANCELED:
                    finish();
                    break;                  
                default:
                    super.onActivityResult(requestCode, resultCode, data);
            }
        }
    }

另外仅供参考,installCertificate() 是从 onCreate() 调用的。

请帮助我。任何帮助将不胜感激。


查询: 当提示输入证书名称时,输入的文本将作为选中状态出现,并且在方向更改时出现剪切/复制选项。任何人都知道如何在提示出现时停止文本选择?!!!

【问题讨论】:

    标签: android certificate


    【解决方案1】:

    我使用以下 Java 代码检查我的证书是否已安装:

    try
    {
        KeyStore ks = KeyStore.getInstance("AndroidCAStore");
        if (ks != null) 
        {
            ks.load(null, null);
            Enumeration aliases = ks.aliases();
            while (aliases.hasMoreElements()) 
            {
                String alias = (String) aliases.nextElement();
                java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) ks.getCertificate(alias);
    
                if (cert.getIssuerDN().getName().contains("MyCert")) 
                {
                    isCertExist = true;
                    break;
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (java.security.cert.CertificateException e) {
        e.printStackTrace();
    }
    

    【讨论】:

    • 我正在使用你的代码,我应该用什么来代替 AndroidCAStore ?
    【解决方案2】:

    KeyChain.createInstallIntent,创建的intent会调用android.security.certinstaller安装证书,安装证书时certinstaller会打印log。因此您可以转储日志猫以检查是否安装了证书。(如果用户更改了证书的存储名称,您可以获得别名)

    【讨论】:

      【解决方案3】:

      从受信任的 CA 存储中读取如下

      KeyStore ks = KeyStore.getInstance("AndroidCAStore");
      

      只会获取 CA 证书,而不是用户/客户端证书。客户端证书不必与 CA 证书共享同一个别名。

      【讨论】:

        【解决方案4】:

        在@Android 的回答中添加一些附加信息(我还不能发表评论),其代码仅适用于 Android 4.0 或更高版本的设备。

        对于 IceCream Sandwich (API

        boolean isCertExist;
            TrustManagerFactory tmf;
            try {
                tmf = TrustManagerFactory.getInstance(TrustManagerFactory
                        .getDefaultAlgorithm());
        
                tmf.init((KeyStore) null);
        
                X509TrustManager xtm = (X509TrustManager) tmf.getTrustManagers()[0];
                for (X509Certificate cert : xtm.getAcceptedIssuers()) {
                    if (cert.getIssuerDN().getName().contains("MyCert")) {
                        isCertExist = true;
                        break;
                    }
                }
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (KeyStoreException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        

        对于搭载 Android 4.0 及更高版本 (API >= 14) 的设备:

        boolean isCertExist;
            try 
            {
                KeyStore ks = KeyStore.getInstance("AndroidCAStore");
                if (ks != null) 
                {
                    ks.load(null, null);
                    Enumeration aliases = ks.aliases();
                    while (aliases.hasMoreElements()) 
                    {
                        String alias = (String) aliases.nextElement();
                        java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) ks.getCertificate(alias);
        
                        if (cert.getIssuerDN().getName().contains("MyCert")) {
                            isCertExist = true;
                            break;
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (java.security.cert.CertificateException e) {
                e.printStackTrace();
            }
        

        【讨论】:

        • 使用此方法我正确地从 KeyStore 获取证书,即使用户尚未在 Intent KeyStore.createInstallIntent() 打开的模式中键入密码和证书名称
        猜你喜欢
        • 2017-11-06
        • 2022-12-13
        • 1970-01-01
        • 2018-11-16
        • 1970-01-01
        • 2017-04-07
        • 1970-01-01
        • 1970-01-01
        • 2011-05-26
        相关资源
        最近更新 更多