将多个SSL证书添加到Android KeyStore不起作用. (来自资源文件) [英] Add multiple SSL certificate pinning to Android KeyStore doesn't work. (from Resource file)
本文介绍了将多个SSL证书添加到Android KeyStore不起作用. (来自资源文件)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想从资源文件向Android KeyStore添加多个SSL证书,如下所示:
I want to add multiple SSL certificates from a ressource file to the Android KeyStore as follow:
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;
仅文件的最后一个证书有效! 看来证书覆盖了另一个证书.
Only the last certificate of the file works! It seems the certificate overwrites the other one.
文件如下:
-----BEGIN CERTIFICATE-----
cert
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
cert
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
cert
-----END CERTIFICATE-----
我希望有人能帮助我! :)
I hope somebody can help me! :)
推荐答案
感谢@Dan Getz,现在可以使用.
Thx to @Dan Getz, now it works.
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上下文:
Then using the SSL context:
client = okHttpClient.newBuilder()
.sslSocketFactory(getSslContext(context).getSocketFactory())
.build();
2.通过指纹通过OkHttp固定非根证书的解决方案:
固定非根CA,我使用的是OkHttp中的CertificatePinner
(!这不适用于自签名证书-根CA):
Pinning a non root CA, I'm using the CertificatePinner
from OkHttp (! this does not work for self-signed certificate - root CAs):
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();
这篇关于将多个SSL证书添加到Android KeyStore不起作用. (来自资源文件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文