当前位置: 首页 > 面试题库 >

将多个SSL证书添加到Android KeyStore不起作用。(来自资源文件)

花阳辉
2023-03-14
问题内容

我想从资源文件向Android KeyStore添加多个SSL证书,如下所示:

if (sslContext==null) {
        // loading CA from an InputStream
        InputStream is = AVApplication.getContext().getResources().openRawResource(R.raw.wildcard);
        String certificates = Converter.convertStreamToString(is);
        String certificateArray[] = certificates.split("-----BEGIN CERTIFICATE-----");

        for (int i = 1; i < certificateArray.length; i++) {
            certificateArray[i] = "-----BEGIN CERTIFICATE-----" + certificateArray[i];
            //LogAV.d("cert:" + certificateArray[i]);

            // generate input stream for certificate factory
            InputStream stream = IOUtils.toInputStream(certificateArray[i]);

            // CertificateFactory
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            // certificate
            Certificate ca;
            try {
                ca = cf.generateCertificate(stream);
            } finally {
                is.close();
            }

            // creating a KeyStore containing our trusted CAs
            KeyStore ks = KeyStore.getInstance("BKS");
            ks.load(null, null);
            ks.setCertificateEntry("av-ca" + i, ca);

            // TrustManagerFactory
            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
            // Create a TrustManager that trusts the CAs in our KeyStore
            tmf.init(ks);

            // Create a SSLContext with the certificate that uses tmf (TrustManager)
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
        }

    }

    return sslContext;

仅文件的最后一个证书有效!看来证书覆盖了另一个证书。

文件看起来像:

-----BEGIN CERTIFICATE-----
    cert 
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
    cert 
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
    cert 
-----END CERTIFICATE-----

我希望有人能帮助我!:)


问题答案:

感谢@Dan Getz,现在可以使用了。

1.具有SSL上下文和自签名证书的解决方案:

public static SSLContext getSSLContext() throws Exception {
        if (sslContext==null) {
            // loading CA from an InputStream
            InputStream is = AVApplication.getContext().getResources().openRawResource(R.raw.certificates);
            String certificates = Converter.convertStreamToString(is);
            String certificateArray[] = certificates.split("-----BEGIN CERTIFICATE-----");

            // creating a KeyStore containing our trusted CAs
            KeyStore ks = KeyStore.getInstance("BKS");
            ks.load(null, null);
            for (int i = 1; i < certificateArray.length; i++) {
                certificateArray[i] = "-----BEGIN CERTIFICATE-----" + certificateArray[i];
                //LogAV.d("cert:" + certificateArray[i]);

                // generate input stream for certificate factory
                InputStream stream = IOUtils.toInputStream(certificateArray[i]);

                // CertificateFactory
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                // certificate
                Certificate ca;
                try {
                    ca = cf.generateCertificate(stream);
                } finally {
                    is.close();
                }

                ks.setCertificateEntry("av-ca" + i, ca);
            }
            // TrustManagerFactory
            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
            // Create a TrustManager that trusts the CAs in our KeyStore
            tmf.init(ks);

            // Create a SSLContext with the certificate that uses tmf (TrustManager)
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
        }

        return sslContext;
    }

然后使用SSL上下文:

client = okHttpClient.newBuilder()
         .sslSocketFactory(getSslContext(context).getSocketFactory())
         .build();

2.通过指纹通过OkHttp固定非根证书的解决方案:

固定 根CA,我使用的CertificatePinner是OkHttp中的from(!不适用于自签名证书-根CA):

CertificatePinner = new CertificatePinner.Builder()
            .add(new URL(url).getHost(), "sha256/<certificate1 fingerprint [base64]>")
            .add(new URL(url).getHost(), "sha256/<certificate2 fingerprint [base64]>")
            .build();
OkHttpClient client;
    client = okHttpClient.newBuilder()
        .certificatePinner(certificatePinner)
        .build();


 类似资料:
  • 你可以添加 SSH 或 SSL 证书来连接你的实例。若要配置 SSH 或 SSL 证书,请前往“配置”->“SSH 或 SSL 证书”。 添加 SSH 证书 若要创建一个新证书,请点击“+ 新建证书”并选择“SSH 证书”。 名 SSH 证书的名。 私钥 粘贴私钥文件的内容。 添加 SSL 证书 若要创建一个新证书,请点击“+ 新建证书”并选择“SSL 证书”。 名 SSL 证书的名。 CA 证书

  • 问题内容: 我在java和cxf中有一个用客户端证书连接到WebServices的应用程序。 我从WebService所有者那里获得了证书 证书 证书 certificate.crt Trusted_ca.cer root_ca.cer 我直接将这个p12证书转换为java要求的有效jks密钥库时遇到问题。 我这样做: 但是此jks不起作用,使用此证书时我收到HTTP响应‘403:Forbidde

  • 我正在使用 karaf 4.0.5 和 osgi 进行一个项目。我们有客户端代码来调用 REST API,这需要加载 3 个“*.属性”文件。我得到了一个客户端jar,我用它来调用服务器端类和方法(包含我无法更新的代码)。所需的属性文件存在于提供的客户端 jar 中,但其代码仍无法找到并加载它们。 在调试我的pax考试时,我发现它没有从jar加载资源文件的可能原因如下。 用于加载文件的代码似乎仅尝

  • 我的GF4和SSL有一些问题。 我已经安装了GF4,并在本教程中列出了所有更改 一切顺利,但现在,我想使用GF服务器在线和prudutiv环境,我想改变SSL证书买一个。我已经买了一个SSL123 Thawte SSL证书,这只是域名签名(对初学者来说应该足够了)。现在我有了. key的. csr和. crt文件。我已经看了,如何导入一个给定的密钥和阴极射线管文件到现有的密钥存储。( 现在,如果我

  • 给了我一个错误: javax.net.ssl.sslHandShakeException:Sun.Security.Validator.ValidatorException:PKIX路径构建失败:Sun.Security.Provider.CertPath.SunCertPathBuilderException:找不到请求目标的有效证书路径

  • 我正在尝试将日志从单台机器上的不同目录收集到本地文件系统文件或 HDFS。 我已经注册了 2 个来源 r1、r2。两个源都指向单通道C1。有一个接收器连接到通道。K1 请找到下面的配置文件: 但是当我使用代理 a1 启动 Flume 时,只有一个源 (r2) 正在启动。水槽代理启动日志: 谢谢