感谢@Dan Getz,现在可以使用了。
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 factoryInputStream stream = IoUtils.toInputStream(certificateArray[i]);// CertificateFactoryCertificateFactory cf = CertificateFactory.getInstance('X.509');// certificateCertificate 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();
固定 根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();解决方法
我想从资源文件向Android KeyStore添加多个SSL证书,如下所示:
if (sslContext==null) {// loading CA from an InputStreamInputStream 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-----
我希望有人能帮助我!:)