我有我自己的PKI基础设施为我的web服务器与CA和中间CA。然后我有一个由中间CA签署的web证书,我希望我的应用程序与服务器通信。根据Developer文档,解决方案是创建我自己的密钥存储库。因此,我将根CA证书与应用程序捆绑在一起,并试图看看这是否可行。它没有,我得到了以下错误:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
我的问题是。由于SSL证书是由我的中间CA签名的,所以我应该将该证书导入到自定义密钥存储库中,还是两者都需要,或者这里还有其他问题?
最终,使用由不受Android信任的CA签署的SSL证书,这是正确的方法吗?
谢谢!
下面是设置keystore管理器的代码。public SSLContext getTrusted() throws Exception{
// Load CAs from an InputStream
CertificateFactory cf = CertificateFactory.getInstance("X.509");
AssetManager assManager = context.getAssets();
InputStream is = null;
try {
is = assManager.open("ca.cert.crt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.d("TrustMan", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
return context;
}
然后我试着这样使用它。
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
TrustMan tm = new TrustMan(context);
SSLContext sslContext;
sslContext = tm.getTrusted();
connection.setSSLSocketFactory(sslContext.getSocketFactory());
代码确实可以工作,但当我从类返回SSLContext时就不行。我调整了类以返回TrustManagerFactory,现在使用中间CA证书可以正常工作了!
谢谢!