验证Android应用程序证书

时间:2015-11-16 09:31:19

标签: android security certificate x509 signature

我想检查安装的Android应用程序是否具有自签名或可信证书。问题是我下面列出的代码会为所有已安装的(包括谷歌制作的)应用程序引发CertificateException。你能帮我找一个问题,为什么它不能正常工作?

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    List<ResolveInfo> runningServices = getPackageManager().queryIntentActivities(intent, 0);
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    KeyStore ks = KeyStore.getInstance("AndroidCaStore");
    ks.load(null, null);
    tmf.init(ks);
    X509TrustManager trustManager = (X509TrustManager)tmf.getTrustManagers()[0];
    PackageManager manager = getPackageManager();
    try {
        for (ResolveInfo runningService : runningServices) {
            PackageInfo info = manager.getPackageInfo(runningService.activityInfo.packageName,
                    PackageManager.GET_SIGNATURES);

            Signature signature = info.signatures[0];
            Signature[] arrSignatures = info.signatures;
            for (Signature sig : arrSignatures) {
                byte[] rawCert = sig.toByteArray();
                InputStream certStream = new ByteArrayInputStream(rawCert);

                CertificateFactory certFactory;
                X509Certificate x509Cert;
                try {
                    certFactory = CertificateFactory.getInstance("X509");
                    x509Cert = (X509Certificate) certFactory.generateCertificate(certStream);
                    trustManager.checkServerTrusted(new X509Certificate[] { x509Cert }, "RSA");
                }
                catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

1 个答案:

答案 0 :(得分:0)

答案非常明显:我们无法使用受信任的证书链验证Android应用程序证书(通常用ssl guts来检查Web资源证书),因为它们是自签名的。这就是checkServerTrusted函数在此类检查期间引发CertificateException的原因。此book提供以下信息:

  

因为进程与包名绑定,并且包名是   与签名相关联,签名在保护数据方面发挥着作用   属于一个包。包通常用a签名   自签名PKI(公钥基础结构)证书。证书   识别包的作者是谁。这些证书需要   不是由证书颁发机构颁发的。这意味着信息   证书未经任何机构批准或验证。这个   意味着可以创建一个证明其姓名的证书   谷歌。唯一的保证是保留此包名称   该用户如果之前没有人在市场上声称它,那么任何人   该包的后续更新仅提供给该用户   (由该证书确定)。