我的Android应用程序连接到用户提供的 URL 。如果是HTTPS连接,如果服务器的证书是由Android的TrustManager中已经存在的CA颁发的,那么一切都很好。
但是如果服务器使用自签名证书,我如何获得该证书并在第一次连接时将其存储在TrustManager中?
我正在使用OkHttp
库来执行网络任务。我目前的解决方案迫使我在开发期间在应用程序的raw
文件夹中添加证书,但这不适用于上述场景。我目前使用的代码如下:
private KeyStore readKeyStore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "testPass";
InputStream is = null;
try {
is = activity.getApplicationContext().getResources().openRawResource(R.raw.server_key);
ks.load(is, password.toCharArray());
} finally {
if (is != null)
is.close();
}
return ks;
}
private OkHttpClient getOkHttpClient() throws CertificateException, IOException, KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(readKeyStore());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(readKeyStore(), "testPass".toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
return new OkHttpClient().setSslSocketFactory(sslContext.getSocketFactory());
}
答案 0 :(得分:4)
以下是信任管理器回调的一些代码示例:https://stackoverflow.com/a/25992879/2657100。从回调中,您可以存储自签名证书,也可以立即接受它们。 但你不应该这样做。通过接受自签名证书,您可能会连接到虚假或恶意服务器,这些服务器可以窃取个人数据,安装恶意软件并执行其他令人讨厌的事情。
如果服务器提供了您(开发人员)在编译时信任的自签名证书,则可以将证书捆绑到应用程序中,就像您已经在做的那样。如果服务器具有CA签名证书会好得多,但如果您确实需要连接到提供自签名证书的服务器,这将(必须)这样做。
永远不要在运行时接受自签名证书。如果您希望允许用户连接到这些类型的服务器,您可以在接受自签名证书之前显示一条警告消息,如“自担风险”。
答案 1 :(得分:1)
您不应该在第一次连接时添加它。理想情况下,他们应该付钱才能获得由CA签署的适当证书。
但即使这样,您也可能会发现已安装的Java版本不支持受欢迎的新CA,例如Let's Encrypt。
在这些情况下,您可以使用keytool为JVM手动添加单个证书或新CA,也可以通过标准Android机制加载。
或者您可以将其与应用捆绑在一起。此示例代码显示了如何使用Merged TrustStore https://github.com/yschimke/oksocial/blob/master/src/main/java/com/baulsupp/oksocial/security/CertificateUtils.java
加载现有系统证书之外的捆绑证书