如何为Android和iOS查找可信证书?

时间:2016-03-28 00:59:06

标签: android ios certificate truststore

免责声明这是自我问答

当我们的客户购买了被认为是“受信任的”证书时,我曾多次遇到这种情况。在iOS上,但不幸的是在Android上它没有用。

原因是什么以及如何解决?

1 个答案:

答案 0 :(得分:1)

简短的回答是购买普通可信证书。

原因是Android设备上的信任存储包含不同的可信证书集--IOS和Android可信证书是不同的。

可以在集合中描述:
A - android可信证书
我 - iOS可信证书
AI - 可信证书的交集

因此,我们需要这两个平台的交集。

然而,这个问题变得更加复杂,因为Android和iOS的操作系统版本的受信任证书集都是varys。这意味着我们需要查看所有支持的平台及其所有支持的版本,以查找常用的受支持证书集。

对于iOS,可信证书列表可在其官方网站list of supported iOS certificates

上找到

对于Android,我找不到相同的列表,但可以通过下面的代码从运行时获取它。

 public List<CertificateDto> getCertificates() {
        List<CertificateDto> result = new ArrayList<>();
        try {
            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algorithm);
            trustManagerFactory.init((KeyStore) null);

            X509TrustManager xtm = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
            for (X509Certificate cert : xtm.getAcceptedIssuers()) {
                PublicKey publicKey = cert.getPublicKey();
                int leyLength = 0;
                if (publicKey instanceof RSAPublicKey) {
                    leyLength = ((RSAPublicKey) publicKey).getModulus().bitLength();
                } else if (publicKey instanceof DSAPublicKey) {
                    leyLength = ((DSAPublicKey) publicKey).getY().bitLength();
                }

                CertNameToValidNameConverter validNameConverter = new CertNameToValidNameConverter();

                CertificateDto certificate = new CertificateDto();
                certificate.setSubjectName(validNameConverter.convert(cert.getSubjectDN().getName()));
                certificate.setIssuerName(validNameConverter.convert(cert.getIssuerDN().getName()));
                certificate.setKeyLength(leyLength);
                certificate.setTypeAlg(cert.getSigAlgName());
                certificate.setExpirationDate(cert.getNotAfter().getTime());

                result.add(certificate);
            }
        } catch (NoSuchAlgorithmException e) {
            Log.e(App.TAG, "Failed obtain list of certificates", e);
        } catch (KeyStoreException e) {
            Log.e(App.TAG, "Failed obtain list of certificates", e);
        }
        return result;
    }

当您从支持的Android操作系统获取证书列表时,您需要编写脚本来查看所有证书,并将其与来自不同支持的Android版本的其他列表进行比较,然后再与iOS版本进行比较。您需要比较证书名称,颁发者名称,算法类型,符号算法和密钥长度。到期日期也用于验证,但您可以省略它。

我通过解析来自excel的证书来实现此脚本 IOS 8,9 Android 6.0,4.4和4.1。

您可以在下面找到的最终证书列表。从~220 IOS证书和~150个证书,您只能使用~65个证书用于两个平台

list of supported certificates for both Android and iOS (google drive link)